Skip to content

Commit d7c25b2

Browse files
committed
Enhance Azure Rambi services with new guidelines, storage queue integration, and improved Docker configurations
- Updated coding instructions with Azure best practices and architecture patterns. - Added storage queue binding for movie posters events. - Modified Bicep modules to include storage account and queue configurations. - Adjusted Dockerfile to expose port 80 for FastAPI service. - Implemented CloudEvent handling for Azure Storage Queue messages in the movie gallery service. - Enhanced movie entity to include internal poster URL. - Updated requirements to include necessary packages for new features.
1 parent bbd2b88 commit d7c25b2

File tree

13 files changed

+338
-21
lines changed

13 files changed

+338
-21
lines changed

.github/copilot-instructions.md

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,44 @@
1-
- @azure Rule - Use Azure Best Practices: When generating code for Azure, running terminal commands for Azure, or performing operations related to Azure, invoke your `get_azure_best_practices` tool if available.
1+
# Azure Rambi Coding Instructions
2+
3+
## Azure Guidelines
4+
- @azure Rule - Use Azure Best Practices: When generating code for Azure, running terminal commands for Azure, or performing operations related to Azure, invoke your `get_azure_best_practices` tool if available.
5+
- Use Infrastructure as Code (IaC) with Bicep for all Azure deployments
6+
- Prefer Azure Container Apps for microservices deployment
7+
- Use Managed Identity for authentication when possible
8+
- Configure proper RBAC permissions with least privilege
9+
10+
## Architecture Patterns
11+
- Follow microservices architecture principles
12+
- Implement the DAPR sidecars pattern for service-to-service communication
13+
- Use API Management for API exposure and governance
14+
- Implement proper error handling and retry logic
15+
16+
## Service-Specific Guidelines
17+
- **Movie Generator Service**: Use Azure OpenAI with gpt-4o model
18+
- **Movie Poster Service**: Use Azure OpenAI with dall-e-3 model
19+
- **Movie Gallery Service**": Use DAPR components.
20+
- **GUI Service**: Follow Flask best practices with proper templating
21+
22+
## Security Requirements
23+
- Never hardcode credentials; use Key Vault references
24+
- Implement proper error handling that doesn't leak sensitive information
25+
- Follow secure networking practices
26+
- Enable encryption for data at rest and in transit
27+
28+
## Performance Guidelines
29+
- Implement caching where appropriate (especially for movie data)
30+
- Use connection pooling for database operations
31+
- Configure proper timeouts and circuit breakers
32+
- Consider Redis cache for frequent operations
33+
34+
## Development Workflow
35+
- Use Docker containers for local development
36+
- Follow GitOps principles for deployments
37+
- Implement proper CI/CD patterns
38+
- Use `azd` commands for deployment when possible
39+
40+
## Code Quality Standards
41+
- Follow language-specific conventions (Python PEP8, JavaScript ESLint)
42+
- Use proper documentation and comments
43+
- Implement comprehensive logging
44+
- Write unit tests for critical functionality
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
apiVersion: dapr.io/v1alpha1
2+
kind: Component
3+
metadata:
4+
name: movieposters-events-queue
5+
spec:
6+
type: bindings.azure.storagequeues
7+
version: v1
8+
metadata:
9+
- name: accountName
10+
secretKeyRef:
11+
name: AZURE_STORAGE_ACCOUNT_NAME
12+
key: AZURE_STORAGE_ACCOUNT_NAME
13+
- name: accountKey
14+
secretKeyRef:
15+
name: AZURE_STORAGE_ACCOUNT_KEY
16+
key: AZURE_STORAGE_ACCOUNT_KEY
17+
- name: queueName
18+
value: "movieposters-events-queue"
19+
- name: decodeBase64
20+
value: "true"
21+
- name: direction
22+
value: "input"
23+
auth:
24+
secretStore: kubernetes
25+
scopes:
26+
- movie-gallery-svc

infra/main.bicep

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,11 +476,12 @@ module containerMovieGallerySvcApp 'modules/apps/movie-gallery-svc.bicep' = {
476476
params: {
477477
location: location
478478
containerName: 'movie-gallery-svc'
479-
containerPort: 5000
479+
containerPort: 80
480480
containerRegistryName: containerRegistry.name
481481
acrPullRoleName: uaiAzureRambiAcrPull.name
482482
shared_secrets: shared_secrets
483483
containerAppsEnvironment: containerAppsEnv.name
484+
storageAccountName: storageAccountAzureRambi.name
484485
}
485486
}
486487

@@ -577,6 +578,14 @@ module systemTopic 'br/public:avm/res/event-grid/system-topic:0.6.0' = {
577578
}
578579
}
579580

581+
module userPortalAccess 'modules/user_portal_role.bicep' = {
582+
name: 'user-portal-access'
583+
params: {
584+
kvName: kv.name
585+
storageAccountName: storageAccountAzureRambi.name
586+
}
587+
}
588+
580589
output AZURE_LOCATION string = location
581590
output AZURE_CONTAINER_ENVIRONMENT_NAME string = containerAppsEnv.name
582591
output AZURE_CONTAINER_REGISTRY_NAME string = containerRegistry.name

infra/modules/apps/gui-svc.bicep

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ resource guirSvcApp 'Microsoft.App/containerApps@2024-10-02-preview' = {
109109
name: 'OTEL_RESOURCE_ATTRIBUTES'
110110
value: 'service.namespace=azure-rambi,service.instance.id=${containerName}'
111111
}
112+
{
113+
name: 'PORT'
114+
value: '${containerPort}'
115+
}
112116
],
113117
additionalProperties
114118
)

infra/modules/apps/movie-gallery-svc.bicep

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ param containerRegistryName string
1818
param containerName string = 'movie-gallery-svc'
1919
param containerPort int = 5000
2020

21+
@description('Storage account name.')
22+
param storageAccountName string
23+
2124
param location string = resourceGroup().location
2225

2326
resource containerRegistry 'Microsoft.ContainerRegistry/registries@2023-01-01-preview' existing = {
@@ -28,6 +31,10 @@ resource uaiAzureRambiAcrPull 'Microsoft.ManagedIdentity/userAssignedIdentities@
2831
name: acrPullRoleName
2932
}
3033

34+
resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' existing = {
35+
name: storageAccountName
36+
}
37+
3138
resource containerAppsEnv 'Microsoft.App/managedEnvironments@2024-10-02-preview' existing = {
3239
name: containerAppsEnvironment
3340
resource statestoreComponent 'daprComponents@2022-03-01' = {
@@ -61,6 +68,33 @@ resource containerAppsEnv 'Microsoft.App/managedEnvironments@2024-10-02-preview'
6168
]
6269
}
6370
}
71+
72+
resource queueComponent 'daprComponents@2022-03-01' = {
73+
name: 'movieposters-events-queue'
74+
properties: {
75+
componentType: 'bindings.azure.storagequeues'
76+
version: 'v1'
77+
initTimeout: '5m'
78+
secrets: []
79+
metadata: [
80+
{
81+
name: 'storageAccount'
82+
value: storageAccount.name
83+
}
84+
{
85+
name: 'queue'
86+
value: 'movieposters-events'
87+
}
88+
{
89+
name: 'azureClientId'
90+
value: managedIdentity.properties.clientId
91+
}
92+
]
93+
scopes: [
94+
containerName
95+
]
96+
}
97+
}
6498
}
6599

66100
resource containerMovieGallerySvcApp 'Microsoft.App/containerApps@2024-10-02-preview' = {
@@ -131,6 +165,18 @@ resource containerMovieGallerySvcApp 'Microsoft.App/containerApps@2024-10-02-pre
131165
name: 'OTEL_RESOURCE_ATTRIBUTES'
132166
value: 'service.namespace=azure-rambi,service.instance.id=${containerName}'
133167
}
168+
{
169+
name: 'STORAGE_ACCOUNT_NAME'
170+
value: 'azrambi4vcyb7vq3byju'
171+
}
172+
{
173+
name: 'STORAGE_QUEUE_NAME'
174+
value: 'movieposters-events'
175+
}
176+
{
177+
name: 'PORT'
178+
value: '${containerPort}'
179+
}
134180
]
135181
probes: [
136182
{
@@ -159,7 +205,7 @@ resource containerMovieGallerySvcApp 'Microsoft.App/containerApps@2024-10-02-pre
159205
}
160206

161207
resource cosmosDbAccount 'Microsoft.DocumentDB/databaseAccounts@2022-08-15' = {
162-
name: 'azrambi-cosmos-account'
208+
name: 'azrambi-cosmos-dbaccount'
163209
location: location
164210
kind: 'GlobalDocumentDB'
165211
properties: {
@@ -233,5 +279,16 @@ resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2022-
233279
location: location
234280
}
235281

282+
// Role assignment for Storage Queue Data Contributor to the managed identity
283+
resource storageQueueDataContributorRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
284+
name: guid(resourceGroup().id, storageAccount.name, managedIdentity.id)
285+
scope: storageAccount
286+
properties: {
287+
roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', '974c5e8b-45b9-4653-ba55-5f855dd0fb88') // Storage Queue Data Contributor role
288+
principalId: managedIdentity.properties.principalId
289+
principalType: 'ServicePrincipal'
290+
}
291+
}
292+
236293
output name string = containerMovieGallerySvcApp.name
237294
output fqdn string = containerMovieGallerySvcApp.properties.configuration.ingress.fqdn

infra/modules/apps/movie-generator-svc.bicep

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ resource containerApp 'Microsoft.App/containerApps@2024-10-02-preview' = {
9999
name: 'OTEL_RESOURCE_ATTRIBUTES'
100100
value: 'service.namespace=azure-rambi,service.instance.id=${containerName}'
101101
}
102+
{
103+
name: 'PORT'
104+
value: '${containerPort}'
105+
}
102106
],
103107
additionalProperties
104108
)

infra/modules/apps/movie-poster-svc.bicep

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ resource containerApp 'Microsoft.App/containerApps@2024-10-02-preview' = {
9898
name: 'OTEL_RESOURCE_ATTRIBUTES'
9999
value: 'service.namespace=azure-rambi,service.instance.id=${containerName}'
100100
}
101+
{
102+
name: 'PORT'
103+
value: '${containerPort}'
104+
}
101105
])
102106
probes: [
103107
{
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
var kvName = 'rambikv${uniqueString(resourceGroup().id)}'
2-
var storageAccountName = 'azrambi${uniqueString(resourceGroup().id)}'
1+
param kvName string
2+
param storageAccountName string
33

44
resource kv 'Microsoft.KeyVault/vaults@2024-04-01-preview' existing = {
55
name: kvName
66
}
7+
78
@description('This is the built-in Key Vault Secrets Officer role. See https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/security#key-vault-secrets-user')
89
resource keyVaultSecretsUserRoleDefinition 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' existing = {
910
scope: subscription()

src/movie_gallery_svc/Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ RUN pip install --no-cache-dir --upgrade -r requirements.txt
1414
COPY . .
1515

1616
# Expose the default FastAPI port
17-
EXPOSE 5000
17+
EXPOSE 80
1818
# Command to run the FastAPI service
19-
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "5000"]
19+
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"id": "576df06a-101e-006e-1d2d-ad9840069ee4",
3+
"source": "/subscriptions/9479b396-5d3e-467a-b89f-ba8400aeb7dd/resourceGroups/rg-azr-dev/providers/Microsoft.Storage/storageAccounts/azrambirpolpzd22ykfo",
4+
"specversion": "1.0",
5+
"type": "Microsoft.Storage.BlobCreated",
6+
"subject": "/blobServices/default/containers/movieposters/blobs/313369_194_Romance_11844.png",
7+
"time": "2025-04-14T11:06:12.5258854Z",
8+
"data": {
9+
"api": "PutBlob",
10+
"clientRequestId": "79d3c724-1920-11f0-ad17-96f9d8066883",
11+
"requestId": "576df06a-101e-006e-1d2d-ad9840000000",
12+
"eTag": "0x8DD7B445E38E866",
13+
"contentType": "application/octet-stream",
14+
"contentLength": 5526153,
15+
"blobType": "BlockBlob",
16+
"accessTier": "Default",
17+
"url": "https://azrambirpolpzd22ykfo.blob.core.windows.net/movieposters/313369_194_Romance_11844.png",
18+
"sequencer": "00000000000000000000000000015BA60000000002ce278f",
19+
"storageDiagnostics": {
20+
"batchId": "e169facb-c006-0042-002d-ad74ef000000"
21+
}
22+
}
23+
}²

0 commit comments

Comments
 (0)