Skip to content

Commit

Permalink
identity to aca environment, roles to acr (#49)
Browse files Browse the repository at this point in the history
## Purpose
refine the whole process
* identity to aca environment
* add container registry roles assignment
* add azd post provision hook to update DB
* update script to fit new version 3.2.5

## Does this introduce a breaking change?
<!-- Mark one with an "x". -->
```
[x] Yes
[ ] No
```

## Pull Request Type
What kind of change does this Pull Request introduce?

<!-- Please check the one that applies to this PR using "x". -->
```
[ ] Bugfix
[x] Feature
[ ] Code style update (formatting, local variables)
[ ] Refactoring (no functional changes, no api changes)
[ ] Documentation content changes
[ ] Other... Please describe:
```
  • Loading branch information
sonwan2020 authored Sep 23, 2024
1 parent 2f87cad commit 7b16473
Show file tree
Hide file tree
Showing 24 changed files with 618 additions and 104 deletions.
31 changes: 23 additions & 8 deletions azure.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json

name: java-microservices-aca-lab
resourceGroup: rg-sonwan-petclinic
resourceGroup: rg-petclinic
infra:
provider: bicep
path: infra/bicep
Expand All @@ -13,7 +13,7 @@ services:
host: containerapp
language: java
docker:
registry: sonwanacr.azurecr.io
registry: <your-acr>.azurecr.io
image: java-microservices-aca-lab/spring-petclinic-api-gateway
tag: passwordless

Expand All @@ -23,7 +23,7 @@ services:
host: containerapp
language: java
docker:
registry: sonwanacr.azurecr.io
registry: <your-acr>.azurecr.io
image: java-microservices-aca-lab/spring-petclinic-customers-service
tag: passwordless

Expand All @@ -33,7 +33,7 @@ services:
host: containerapp
language: java
docker:
registry: sonwanacr.azurecr.io
registry: <your-acr>.azurecr.io
image: java-microservices-aca-lab/spring-petclinic-vets-service
tag: passwordless

Expand All @@ -43,25 +43,40 @@ services:
host: containerapp
language: java
docker:
registry: sonwanacr.azurecr.io
registry: <your-acr>.azurecr.io
image: java-microservices-aca-lab/spring-petclinic-visits-service
tag: passwordless

chat-agent:
resourceName: chat-agent
project: ./src/spring-petclinic-chat-agent
host: containerapp
language: java
docker:
registry: <your-acr>.azurecr.io
image: java-microservices-aca-lab/spring-petclinic-chat-agent
tag: passwordless

admin-server:
resourceName: admin-server
project: ./src/spring-petclinic-admin-server
host: containerapp
language: java
docker:
registry: sonwanacr.azurecr.io
registry: <your-acr>.azurecr.io
image: java-microservices-aca-lab/spring-petclinic-admin-server
tag: passwordless

hooks:
prepackage:
windows:
shell: pwsh
run: 'cd src; .\mvnw.cmd package -DskipTests'
run: 'cd src; .\mvnw.cmd clean package -DskipTests'
posix:
shell: sh
run: 'cd src; chmod +x ./mvnw; ./mvnw clean package -DskipTests'

postprovision:
posix:
shell: sh
run: 'cd src; chmod +x ./mvnw; ./mvnw package -DskipTests'
run: ./infra/bicep/hooks/postprovision.sh
7 changes: 7 additions & 0 deletions infra/bicep/hooks/postprovision.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash

set -x

# refresh service connection, via customers-service
az containerapp connection create mysql-flexible --connection $sqlConnectName --source-id $customersServiceId --target-id $sqlDatabaseId --client-type springBoot \
--user-identity client-id=$appUserIdentityClientId subs-id=$subscriptionId mysql-identity-id=$sqlAdminIdentityId -c $customersServiceName -y
138 changes: 108 additions & 30 deletions infra/bicep/main.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,71 @@ targetScope = 'subscription'

@minLength(2)
@maxLength(32)
@description('Name of the the environment.')
@description('Name of the the azd environment.')
param environmentName string

@minLength(2)
@description('Primary location for all resources.')
param location string

param resourceGroupName string = ''
@description('Name of the the resource group. Default: rg-{environmentName}')
param resourceGroupName string

@description('Name of the the new containerapp environment. Default: aca-env-{environmentName}')
param managedEnvironmentsName string = ''

@description('Boolean indicating the aca environment only has an internal load balancer. ')
param vnetEndpointInternal bool = false

// mysql
@description('Name of the the sql server. Default: sql-{environmentName}')
param sqlServerName string = ''
param sqlAdmin string

@description('Name of the the sql admin.')
param sqlAdmin string = 'sqladmin'

@description('The the sql admin password.')
@secure()
param sqlAdminPassword string

@description('Repo url of the configure server.')
param configGitRepo string

@description('Repo branch of the configure server.')
param configGitBranch string = 'main'

@description('Repo path of the configure server.')
param configGitPath string

param acrRegistry string
param acrIdentityId string
param miClientId string
param miPrincipalId string
param apiGatewayImage string
param customersServiceImage string
param vetsServiceImage string
param visitsServiceImage string
param adminServerImage string
param chatAgentImage string
@description('Name of the azure container registry.')
param acrName string
@description('Resource group of the azure container registry.')
param acrGroupName string = ''
@description('Subscription of the azure container registry.')
param acrSubscription string = ''

@description('Name of the log analytics server. Default la-{environmentName}')
param logAnalyticsName string = ''

@description('Name of the log analytics server. Default ai-{environmentName}')
param applicationInsightsName string = ''

@description('Images for petclinic services, will replaced by new images on step `azd deploy`')
param apiGatewayImage string = ''
param customersServiceImage string = ''
param vetsServiceImage string = ''
param visitsServiceImage string = ''
param adminServerImage string = ''
param chatAgentImage string = ''

@description('Name of the virtual network. Default vnet-{environmentName}')
param vnetName string = ''

var vnetPrefix = '10.1.0.0/16'
var infraSubnetPrefix = '10.1.0.0/24'
var infraSubnetName = '${abbrs.networkVirtualNetworksSubnets}infra'

var placeholderImage = 'azurespringapps/default-banner:distroless-2024022107-66ea1a62-87936983'

var abbrs = loadJsonContent('./abbreviations.json')
var tags = { 'azd-env-name': environmentName }

Expand All @@ -52,11 +77,27 @@ resource rg 'Microsoft.Resources/resourceGroups@2021-04-01' = {
tags: tags
}

module umiAcrPull 'modules/shared/userAssignedIdentity.bicep' = {
name: 'umi-acr-pull'
scope: rg
params: {
name: 'umi-${acrName}-acrpull'
}
}

module umiApps 'modules/shared/userAssignedIdentity.bicep' = {
name: 'umi-apps'
scope: rg
params: {
name: 'umi-apps-${environmentName}'
}
}

module vnet './modules/network/vnet.bicep' = {
name: 'vnet'
scope: rg
params: {
name: '${abbrs.networkVirtualNetworks}${environmentName}'
name: !empty(vnetName) ? vnetName : '${abbrs.networkVirtualNetworks}${environmentName}'
location: location
vnetAddressPrefixes: [vnetPrefix]
subnets: [
Expand Down Expand Up @@ -100,13 +141,36 @@ module applicationInsights 'modules/shared/applicationInsights.bicep' = {
}
}

// group id: /subscriptions/<subscriptionId>/resourceGroups/<groupName>
var acrSub = !empty(acrSubscription) ? acrSubscription : split(rg.id, '/')[2]
var acrGroup = !empty(acrGroupName) ? acrGroupName : rg.name

@description('roles for Azure Container Registry')
module acrRoleAssignments 'modules/shared/containerRegistryRoleAssignment.bicep' = {
name: 'acr-roles-assignments'
scope: resourceGroup(acrSub, acrGroup)
params: {
name: acrName
roleAssignments: [
{
principalId: umiAcrPull.outputs.principalId
roleDefinitionIdOrName: 'AcrPull'
}
]
}
}

module managedEnvironment 'modules/containerapps/aca-environment.bicep' = {
name: 'managedEnvironment'
scope: rg
params: {
name: !empty(managedEnvironmentsName) ? managedEnvironmentsName : 'aca-env-${environmentName}'
location: location
vnetEndpointInternal: vnetEndpointInternal
userAssignedIdentities: {
'${umiAcrPull.outputs.id}': {}
'${umiApps.outputs.id}': {}
}
diagnosticWorkspaceId: logAnalytics.outputs.logAnalyticsWsId
subnetId: first(filter(vnet.outputs.vnetSubnets, x => x.name == infraSubnetName)).id
tags: tags
Expand Down Expand Up @@ -141,7 +205,7 @@ module openai 'modules/ai/openai.bicep' = {
params: {
accountName: 'openai-${environmentName}'
location: location
appPrincipalId: miPrincipalId
appPrincipalId: umiApps.outputs.principalId
}
}

Expand All @@ -153,25 +217,39 @@ module applications 'modules/app/petclinic.bicep' = {
eurekaId: javaComponents.outputs.eurekaId
configServerId: javaComponents.outputs.configServerId
mysqlDBId: mysql.outputs.databaseId
mysqlUserAssignedIdentityClientId: mysql.outputs.userAssignedIdentityClientId
acrRegistry: acrRegistry
acrIdentityId: acrIdentityId
apiGatewayImage: apiGatewayImage
customersServiceImage: customersServiceImage
vetsServiceImage: vetsServiceImage
visitsServiceImage: visitsServiceImage
adminServerImage: adminServerImage
chatAgentImage: chatAgentImage
mysqlUserAssignedIdentityClientId: umiApps.outputs.clientId
acrRegistry: '${acrRoleAssignments.outputs.registryName}.azurecr.io' // add dependency to make sure roles are assigned
acrIdentityId: umiAcrPull.outputs.id
apiGatewayImage: !empty(apiGatewayImage) ? apiGatewayImage : placeholderImage
customersServiceImage: !empty(customersServiceImage) ? customersServiceImage : placeholderImage
vetsServiceImage: !empty(vetsServiceImage) ? vetsServiceImage : placeholderImage
visitsServiceImage: !empty(visitsServiceImage) ? visitsServiceImage : placeholderImage
adminServerImage: !empty(adminServerImage) ? adminServerImage : placeholderImage
chatAgentImage: !empty(chatAgentImage) ? chatAgentImage : placeholderImage
targetPort: 8080
applicationInsightsConnString: applicationInsights.outputs.connectionString
azureOpenAiEndpoint: openai.outputs.endpoint
openAiClientId: acrIdentityId
openAiClientId: umiApps.outputs.id
}
}

output subscriptionId string = subscription().subscriptionId
output resourceGroupName string = rg.name

output gatewayFqdn string = applications.outputs.gatewayFqdn
output adminFqdn string = applications.outputs.adminFqdn
output eurekaId string = javaComponents.outputs.eurekaId
output configServerId string = javaComponents.outputs.configServerId
output databaseId string = mysql.outputs.databaseId
output userAssignedIdentityClientId string = mysql.outputs.userAssignedIdentityClientId

output sqlDatabaseId string = mysql.outputs.databaseId
output sqlAdminIdentityClientId string = mysql.outputs.adminIdentityClientId
output sqlAdminIdentityId string = mysql.outputs.adminIdentityId
output sqlConnectName string = applications.outputs.connectionName

output appUserIdentityClientId string = umiApps.outputs.clientId
output appUserIdentityId string = umiApps.outputs.id

output customersServiceName string = applications.outputs.customersServiceName
output customersServiceId string = applications.outputs.customersServiceId
output vetsServiceName string = applications.outputs.vetsServiceName
output vetsServiceId string = applications.outputs.vetsServiceId
output visitsServiceName string = applications.outputs.visitsServiceName
output visitsServiceId string = applications.outputs.visitsServiceId
46 changes: 17 additions & 29 deletions infra/bicep/main.parameters.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,20 @@
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"environmentName": {
"value": "petclinic"
},
"resourceGroupName": {
"value": "rg-petclinic"
},
"location": {
"value": "westus2"
},
"vnetEndpointInternal": {
"value": false
},
"sqlAdmin": {
"value": "azureuser"
"value": "sqladmin"
},
"sqlAdminPassword": {
"value": "Password#123"
Expand All @@ -17,35 +26,14 @@
"configGitPath": {
"value": "config"
},
"acrRegistry": {
"value": "<your-acr>.azurecr.io"
},
"acrIdentityId": {
"value": "<acr-repo-user-mi-id>"
},
"miClientId": {
"value": "<mi-principal-id>"
},
"miPrincipalId": {
"value": "<mi-client-id>"
},
"apiGatewayImage": {
"value": "java-microservices-aca-lab/spring-petclinic-api-gateway:passwordless"
},
"customersServiceImage": {
"value": "java-microservices-aca-lab/spring-petclinic-customers-service:passwordless"
},
"vetsServiceImage": {
"value": "java-microservices-aca-lab/spring-petclinic-vets-service:passwordless"
},
"visitsServiceImage": {
"value": "java-microservices-aca-lab/spring-petclinic-visits-service:passwordless"
"acrName": {
"value": "<your-acr>"
},
"chatAgentImage": {
"value": "java-microservices-aca-lab/spring-petclinic-chat-agent:passwordless"
"acrGroupName": {
"value": "<your-acr-group>"
},
"adminServerImage": {
"value": "java-microservices-aca-lab/spring-petclinic-admin-server:passwordless"
"acrSubscription": {
"value": "<your-acr-subscription>"
}
}
}
}
11 changes: 10 additions & 1 deletion infra/bicep/modules/app/petclinic.bicep
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ module apiGateway '../containerapps/containerapp.bicep' = {
}
}

module customerService '../containerapps/containerapp.bicep' = {
module customersService '../containerapps/containerapp.bicep' = {
name: 'customers-service'
params: {
location: environment.location
Expand Down Expand Up @@ -201,3 +201,12 @@ module adminServer '../containerapps/containerapp.bicep' = {

output gatewayFqdn string = apiGateway.outputs.appFqdn
output adminFqdn string = adminServer.outputs.appFqdn

output customersServiceName string = customersService.outputs.appName
output customersServiceId string = customersService.outputs.appId
output vetsServiceName string = vetsService.outputs.appName
output vetsServiceId string = vetsService.outputs.appId
output visitsServiceName string = visitsService.outputs.appName
output visitsServiceId string = visitsService.outputs.appId

output connectionName string = customersService.outputs.connectionName
Loading

0 comments on commit 7b16473

Please sign in to comment.