diff --git a/cli/azd/internal/appdetect/appdetect.go b/cli/azd/internal/appdetect/appdetect.go index 122ba242fa6..8d45a55cc87 100644 --- a/cli/azd/internal/appdetect/appdetect.go +++ b/cli/azd/internal/appdetect/appdetect.go @@ -349,6 +349,8 @@ func analyze(projects []Project) []Project { result = append(result, copiedProject) } } + } else { + result = append(result, project) } } return result diff --git a/cli/azd/internal/appdetect/javaanalyze/project_analyzer_java.go b/cli/azd/internal/appdetect/javaanalyze/project_analyzer_java.go index bdb0c9cf38a..fe8abae659f 100644 --- a/cli/azd/internal/appdetect/javaanalyze/project_analyzer_java.go +++ b/cli/azd/internal/appdetect/javaanalyze/project_analyzer_java.go @@ -12,6 +12,7 @@ func Analyze(path string) []AzureYaml { rules := []rule{ &ruleService{}, &ruleMysql{}, + &rulePostgresql{}, &ruleStorage{}, &ruleServiceBusScsb{}, } diff --git a/cli/azd/internal/appdetect/javaanalyze/project_analyzer_spring.go b/cli/azd/internal/appdetect/javaanalyze/project_analyzer_spring.go index 85047325da4..eef378a9836 100644 --- a/cli/azd/internal/appdetect/javaanalyze/project_analyzer_spring.go +++ b/cli/azd/internal/appdetect/javaanalyze/project_analyzer_spring.go @@ -21,7 +21,8 @@ func findSpringApplicationProperties(projectPath string) map[string]interface{} yamlFilePath := projectPath + "/src/main/resources/application.yml" data, err := ioutil.ReadFile(yamlFilePath) if err != nil { - log.Fatalf("error reading YAML file: %v", err) + log.Printf("failed to read spring application properties: %s", yamlFilePath) + return nil } // Parse the YAML into a yaml.Node diff --git a/cli/azd/internal/appdetect/javaanalyze/rule_postgresql.go b/cli/azd/internal/appdetect/javaanalyze/rule_postgresql.go new file mode 100644 index 00000000000..bfe58533428 --- /dev/null +++ b/cli/azd/internal/appdetect/javaanalyze/rule_postgresql.go @@ -0,0 +1,27 @@ +package javaanalyze + +type rulePostgresql struct { +} + +func (mr *rulePostgresql) match(javaProject *javaProject) bool { + if javaProject.mavenProject.Dependencies != nil { + for _, dep := range javaProject.mavenProject.Dependencies { + if dep.GroupId == "org.postgresql" && dep.ArtifactId == "postgresql" { + return true + } + } + } + return false +} + +func (mr *rulePostgresql) apply(azureYaml *AzureYaml) { + azureYaml.Resources = append(azureYaml.Resources, &Resource{ + Name: "PostgreSQL", + Type: "PostgreSQL", + }) + + azureYaml.ServiceBindings = append(azureYaml.ServiceBindings, ServiceBinding{ + Name: "PostgreSQL", + AuthType: AuthType_SYSTEM_MANAGED_IDENTITY, + }) +} diff --git a/cli/azd/resources/scaffold/base/shared/monitoring.bicep b/cli/azd/resources/scaffold/base/shared/monitoring.bicep index 4ae9796cc3b..7b50e45ec24 100644 --- a/cli/azd/resources/scaffold/base/shared/monitoring.bicep +++ b/cli/azd/resources/scaffold/base/shared/monitoring.bicep @@ -30,5 +30,6 @@ resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = { } output applicationInsightsName string = applicationInsights.name +output connectionString string = applicationInsights.properties.ConnectionString output logAnalyticsWorkspaceId string = logAnalytics.id output logAnalyticsWorkspaceName string = logAnalytics.name diff --git a/cli/azd/resources/scaffold/templates/db-postgres.bicept b/cli/azd/resources/scaffold/templates/db-postgres.bicept index 54866987449..b6ebb5a87b8 100644 --- a/cli/azd/resources/scaffold/templates/db-postgres.bicept +++ b/cli/azd/resources/scaffold/templates/db-postgres.bicept @@ -73,6 +73,7 @@ resource dbPasswordKey 'Microsoft.KeyVault/vaults/secrets@2022-07-01' = { } } +output databaseId string = database.id output databaseHost string = postgreServer.properties.fullyQualifiedDomainName output databaseName string = databaseName output databaseUser string = databaseUser diff --git a/cli/azd/resources/scaffold/templates/host-containerapp.bicept b/cli/azd/resources/scaffold/templates/host-containerapp.bicept index 4333fe5ef76..768693889da 100644 --- a/cli/azd/resources/scaffold/templates/host-containerapp.bicept +++ b/cli/azd/resources/scaffold/templates/host-containerapp.bicept @@ -15,6 +15,7 @@ param cosmosDbConnectionString string param postgresDatabaseHost string param postgresDatabaseUser string param postgresDatabaseName string +param postgresDatabaseId string @secure() param postgresDatabasePassword string {{- end}} @@ -127,6 +128,7 @@ resource app 'Microsoft.App/containerApps@2023-05-02-preview' = { allowedOrigins: union(allowedOrigins, [ // define additional allowed origins here ]) + allowedMethods: ['GET', 'PUT', 'POST', 'DELETE'] } {{- end}} } @@ -235,10 +237,10 @@ resource app 'Microsoft.App/containerApps@2023-05-02-preview' = { } } } -{{- if .DbMySql}} +{{- if (or .DbMySql .DbPostgres)}} resource linkerCreatorIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { - name: 'linkerCreatorIdentity' + name: '${name}-linker-creator-identity' location: location } @@ -252,10 +254,12 @@ resource linkerCreatorRole 'Microsoft.Authorization/roleAssignments@2022-04-01' principalId: linkerCreatorIdentity.properties.principalId } } +{{- end}} +{{- if .DbMySql}} resource appLinkToMySql 'Microsoft.Resources/deploymentScripts@2023-08-01' = { dependsOn: [ linkerCreatorRole ] - name: 'appLinkToMySql' + name: '${name}-link-to-mysql' location: location kind: 'AzureCLI' identity: { @@ -273,6 +277,28 @@ resource appLinkToMySql 'Microsoft.Resources/deploymentScripts@2023-08-01' = { } } {{- end}} +{{- if .DbPostgres}} + +resource appLinkToPostgres 'Microsoft.Resources/deploymentScripts@2023-08-01' = { + dependsOn: [ linkerCreatorRole ] + name: '${name}-link-to-postgres' + location: location + kind: 'AzureCLI' + identity: { + type: 'UserAssigned' + userAssignedIdentities: { + '${linkerCreatorIdentity.id}': {} + } + } + properties: { + azCliVersion: '2.63.0' + timeout: 'PT10M' + scriptContent: 'apk update; apk add g++; apk add unixodbc-dev; az extension add --name containerapp; az extension add --name serviceconnector-passwordless --upgrade; az containerapp connection create postgres-flexible --connection appLinkToPostgres --source-id ${app.id} --target-id ${postgresDatabaseId} --client-type springBoot --user-identity client-id=${identity.properties.clientId} subs-id=${subscription().subscriptionId} user-object-id=${linkerCreatorIdentity.properties.principalId} -c main --yes; az tag create --resource-id ${app.id} --tags azd-service-name={{.Name}} ' + cleanupPreference: 'OnSuccess' + retentionInterval: 'P1D' + } +} +{{- end}} output defaultDomain string = containerAppsEnvironment.properties.defaultDomain output name string = app.name diff --git a/cli/azd/resources/scaffold/templates/main.bicept b/cli/azd/resources/scaffold/templates/main.bicept index 2cb3d975ca6..0d8d6fdbcaa 100644 --- a/cli/azd/resources/scaffold/templates/main.bicept +++ b/cli/azd/resources/scaffold/templates/main.bicept @@ -141,10 +141,9 @@ module mysqlDb './app/db-mysql.bicep' = { } scope: rg } - {{- end}} - {{- range .Services}} + module {{bicepName .Name}} './app/{{.Name}}.bicep' = { name: '{{.Name}}' params: { @@ -167,6 +166,7 @@ module {{bicepName .Name}} './app/{{.Name}}.bicep' = { postgresDatabaseName: postgresDb.outputs.databaseName postgresDatabaseHost: postgresDb.outputs.databaseHost postgresDatabaseUser: postgresDb.outputs.databaseUser + postgresDatabaseId: postgresDb.outputs.databaseId postgresDatabasePassword: vault.getSecret(postgresDb.outputs.databaseConnectionKey) {{- end}} {{- if .DbMySql}} @@ -195,4 +195,8 @@ module {{bicepName .Name}} './app/{{.Name}}.bicep' = { output AZURE_CONTAINER_REGISTRY_ENDPOINT string = registry.outputs.loginServer output AZURE_KEY_VAULT_NAME string = keyVault.outputs.name output AZURE_KEY_VAULT_ENDPOINT string = keyVault.outputs.endpoint +output APPLICATIONINSIGHTS_CONNECTION_STRING string = monitoring.outputs.connectionString +{{- range .Services}} +output {{.Name}}_uri string = {{.Name}}.outputs.uri +{{- end}} {{ end}}