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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions samples/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ You can use this folder to share Logic Apps sample.

- [**Sample Logic Apps Workspace**](./sample-logicapp-workspace/): This is a simple request response project, just to exemplify the required structure.
- [**AI Loan Agent**](./ai-loan-agent-sample/): AI-powered loan approval system that automates the evaluation of vehicle loan applications using Azure Logic Apps Standard and Azure OpenAI.
- [**Transaction Repair Agent**](./transaction-repair-agent/): Conversational AI agent that helps operations teams diagnose and repair failed work orders through natural chat interaction. Built with Azure Logic Apps Standard and Azure OpenAI, featuring guided workflows, approval management, and ITSM audit logging.

## How to contribute

Expand Down
203 changes: 203 additions & 0 deletions samples/shared/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
# Shared Infrastructure for Logic Apps Samples

Reusable Bicep modules, templates, and scripts that provide consistent infrastructure across all Logic Apps samples.

## Quick Start

```powershell
# 1. Create folder structure
samples/your-sample-name/
├── Deployment/ # Generated assets (empty initially)
└── LogicApps/ # Your workflows go here

# 2. Generate deployment files
.\samples\shared\scripts\BundleAssets.ps1 -Sample "your-sample-name"

# 3. Deploy infrastructure
az group create --name rg-test --location westeurope
az deployment group create `
--resource-group rg-test `
--template-file samples/your-sample-name/Deployment/main.bicep `
--parameters BaseName=test123

# 4. Upload local workflows (deployment-script 404 is expected!)
az webapp deploy `
--name test123-logicapp `
--resource-group rg-test `
--src-path samples/your-sample-name/Deployment/workflows.zip `
--type zip

# 5. Test your workflows in Azure Portal
```

## Directory Structure

```
shared/
├── modules/ # 6 reusable Bicep modules
│ ├── storage.bicep
│ ├── openai.bicep
│ ├── logicapp.bicep
│ ├── storage-rbac.bicep
│ ├── openai-rbac.bicep
│ └── deployment-script.bicep
├── scripts/
│ └── BundleAssets.ps1 # Generates deployment artifacts
└── templates/
└── main.bicep.template # Infrastructure template
```

## Bicep Modules

Six reusable modules provide complete Logic Apps infrastructure:

| Module | Purpose |
|--------|---------|
| **storage.bicep** | Storage Account for Logic App runtime (managed identity only, HTTPS/TLS 1.2, no shared keys) |
| **openai.bicep** | Azure OpenAI S0 with gpt-4o-mini model (GlobalStandard, 150K tokens) |
| **logicapp.bicep** | Logic App Standard with App Service Plan (WS1 SKU, system + user-assigned identities) |
| **storage-rbac.bicep** | Storage Blob/Queue/Table Data Contributor roles for Logic App |
| **openai-rbac.bicep** | Cognitive Services OpenAI User role for Logic App |
| **deployment-script.bicep** | Downloads and deploys workflows.zip using deployment script |

## BundleAssets.ps1 Script

Generates all deployment artifacts for a sample:

```powershell
.\samples\shared\scripts\BundleAssets.ps1 -Sample "your-sample-name"
```

**Generates:**
1. `main.bicep` - From template (only if doesn't exist, preserves customizations)
2. `sample-arm.json` - Compiled ARM template
3. `workflows.zip` - Bundled LogicApps folder

**How it works:**
- Uses hardcoded `Azure/logicapps-labs` main branch for upstream URLs
- Never overwrites existing `main.bicep` (delete to regenerate)
- Replaces `{{WORKFLOWS_ZIP_URL}}` template placeholder with upstream URL
- Requires Bicep CLI and PowerShell 5.1+

**Why upstream URLs?** The generated `workflowsZipUrl` parameter points to the upstream main branch so the "Deploy to Azure" button works for end users. The deployment-script module downloads and deploys workflows.zip from this URL automatically. For local testing before merge, use `az webapp deploy` to upload your local zip file instead.

## Creating a New Sample

### 1. Create Folder Structure

```
samples/your-sample-name/
├── Deployment/ # Empty (generated by script)
└── LogicApps/ # Your workflows
├── host.json
├── connections.json
└── YourWorkflow/
└── workflow.json
```

### 2. Generate Deployment Files

```powershell
.\samples\shared\scripts\BundleAssets.ps1 -Sample "your-sample-name"
```

Creates `Deployment/main.bicep` with:
- 6 shared module references
- `workflowsZipUrl` parameter pointing to upstream main (for "Deploy to Azure" button)
- Standard BaseName and location parameters

The upstream URL enables the deployment-script module to automatically download and deploy workflows.zip when users click "Deploy to Azure".

### 3. Customize (Optional)

Edit `Deployment/main.bicep` to add sample-specific resources or configurations. The script won't overwrite your changes.

### 4. Test Locally

```powershell
# Create resource group (use supported region)
az group create --name rg-test --location westeurope

# Deploy infrastructure
az deployment group create `
--resource-group rg-test `
--template-file samples/your-sample-name/Deployment/main.bicep `
--parameters BaseName=test123

# Upload local workflows (deployment-script 404 is normal!)
az webapp deploy `
--name test123-logicapp `
--resource-group rg-test `
--src-path samples/your-sample-name/Deployment/workflows.zip `
--type zip

# Test workflows in Azure Portal
```

### 5. Commit After Testing

```powershell
git add samples/your-sample-name/
git commit -m "Add your-sample-name sample"
git push
```

## Local Testing Details

### Prerequisites

- Azure CLI and Bicep CLI installed
- Azure subscription with:
- Azure OpenAI access ([request here](https://aka.ms/oai/access))
- Logic Apps Standard quota
- Supported regions: **eastus2**, **westeurope**, **australiaeast**

### Expected Deployment Behavior

**Infrastructure deployment:**
- ✅ Storage Account deploys successfully
- ✅ Azure OpenAI deploys successfully
- ✅ Logic App deploys successfully
- ✅ RBAC roles assigned successfully
- ❌ **deployment-script fails with 404** - This is **expected**! workflows.zip isn't on main yet.

**Solution:** Use `az webapp deploy` to upload your local workflows.zip directly.

### Validation Checklist

After deployment:
- ✅ All resources visible in Azure Portal
- ✅ Logic App has system + user-assigned managed identities
- ✅ Storage uses managed identity only (no keys)
- ✅ Workflows deployed and visible in Logic App
- ✅ Workflows execute successfully
- ✅ OpenAI connections work

### Troubleshooting

| Issue | Solution |
|-------|----------|
| **Deployment-script 404** | Normal for local testing - use `az webapp deploy` instead |
| **Logic Apps quota error** | Try different region: eastus2, westeurope, or australiaeast |
| **OpenAI access denied** | Request access at https://aka.ms/oai/access |
| **Region not supported** | Use eastus2, westeurope, or australiaeast only |

### Cleanup

```powershell
az group delete --name rg-test --yes --no-wait
```

## Benefits

✅ **Consistency** - All samples use identical infrastructure patterns
✅ **Security** - Managed identity only, RBAC-based, no shared keys
✅ **Simplicity** - One script, three files, ready to deploy
✅ **Testable** - Local testing workflow with `az webapp deploy`
✅ **Maintainable** - Fix modules once, all samples benefit

## Examples

See existing samples:
- [product-return-agent-sample](../product-return-agent-sample/)
- [ai-loan-agent-sample](../ai-loan-agent-sample/)
89 changes: 89 additions & 0 deletions samples/shared/modules/deployment-script.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Deployment Script Module - Deploys workflows.zip to Logic App
// Includes RBAC assignment for deployment identity

@description('Location for the deployment script resource')
param location string

@description('Name for the deployment script resource')
param deploymentScriptName string

@description('User-assigned managed identity ID for deployment')
param userAssignedIdentityId string

@description('Principal ID of the user-assigned managed identity used for deployment')
param deploymentIdentityPrincipalId string

@description('Name of the Logic App to deploy to')
param logicAppName string

@description('Resource group name')
param resourceGroupName string

@description('URL to the workflows.zip file')
param workflowsZipUrl string

// Grant Website Contributor role at resource group level to deployment identity
// This allows the deployment script to deploy code to the Logic App and read the App Service Plan
resource websiteContributorRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, deploymentIdentityPrincipalId, 'de139f84-1756-47ae-9be6-808fbbe84772')
scope: resourceGroup()
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'de139f84-1756-47ae-9be6-808fbbe84772') // Website Contributor
principalId: deploymentIdentityPrincipalId
principalType: 'ServicePrincipal'
}
}

// Deploy workflows.zip to Logic App using Azure CLI
resource workflowDeploymentScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = {
name: deploymentScriptName
location: location
kind: 'AzureCLI'
identity: {
type: 'UserAssigned'
userAssignedIdentities: {
'${userAssignedIdentityId}': {}
}
}
properties: {
azCliVersion: '2.59.0'
retentionInterval: 'PT1H'
timeout: 'PT30M'
cleanupPreference: 'OnSuccess'
environmentVariables: [
{
name: 'LOGIC_APP_NAME'
value: logicAppName
}
{
name: 'RESOURCE_GROUP'
value: resourceGroupName
}
{
name: 'WORKFLOWS_ZIP_URL'
value: workflowsZipUrl
}
]
scriptContent: '''
#!/bin/bash
set -e

echo "Downloading workflows.zip..."
wget -O workflows.zip "$WORKFLOWS_ZIP_URL"

echo "Deploying workflows to Logic App: $LOGIC_APP_NAME"
az functionapp deployment source config-zip \
--resource-group "$RESOURCE_GROUP" \
--name "$LOGIC_APP_NAME" \
--src workflows.zip

echo "Waiting 60 seconds for workflow registration and RBAC propagation..."
sleep 60

echo "Deployment completed successfully"
'''
}
dependsOn: [
websiteContributorRoleAssignment
]
}
Loading