in cli/azd/pkg/apphost/generate.go [1271:1418]
func (b *infraGenerator) Compile() error {
// compile the ingress for all services
// All services's ingress must be compiled before resolving the environment variables below.
if err := b.compileIngress(); err != nil {
return err
}
for resourceName, bc := range b.buildContainers {
var bMounts []*BindMount
if len(bc.BindMounts) > 0 {
// must grant write role to the Storage File Share to upload data
b.bicepContext.RequiresPrincipalId = true
}
for count, bm := range bc.BindMounts {
bMounts = append(bMounts, &BindMount{
// adding a name using the index. This name is used for naming the resource in bicep.
Name: fmt.Sprintf("bm%d", count),
// mount bind is not supported across devices, as it depends on a local path which might be missing in
// another device.
Source: bm.Source,
Target: bm.Target,
ReadOnly: bm.ReadOnly,
})
}
cs := genContainerApp{
Volumes: bc.Volumes,
BindMounts: bMounts,
}
b.bicepContext.ContainerApps[resourceName] = cs
projectTemplateCtx := genContainerAppManifestTemplateContext{
Name: resourceName,
Env: make(map[string]string),
Secrets: make(map[string]string),
KeyVaultSecrets: make(map[string]string),
DeployParams: make(map[string]string),
Ingress: b.allServicesIngress[resourceName].ingress,
Volumes: bc.Volumes,
DeploySource: bc.DeploymentSource,
BindMounts: bMounts,
Entrypoint: bc.Entrypoint,
}
if err := b.buildEnvBlock(bc.Env, &projectTemplateCtx); err != nil {
return fmt.Errorf("configuring environment for resource %s: %w", resourceName, err)
}
if err := b.buildArgsBlock(bc.Args, &projectTemplateCtx); err != nil {
return err
}
if err := b.buildDeployBlock(bc.DeploymentParams, &projectTemplateCtx); err != nil {
return err
}
b.containerAppTemplateContexts[resourceName] = projectTemplateCtx
}
for resourceName, project := range b.projects {
projectTemplateCtx := genContainerAppManifestTemplateContext{
Name: resourceName,
Env: make(map[string]string),
Secrets: make(map[string]string),
KeyVaultSecrets: make(map[string]string),
DeployParams: make(map[string]string),
Ingress: b.allServicesIngress[resourceName].ingress,
DeploySource: project.DeploymentSource,
}
for _, dapr := range b.dapr {
if dapr.Application == resourceName {
appPort := dapr.AppPort
if appPort == nil && projectTemplateCtx.Ingress != nil {
appPort = &projectTemplateCtx.Ingress.TargetPort
}
projectTemplateCtx.Dapr = &genContainerAppManifestTemplateContextDapr{
AppId: dapr.AppId,
AppPort: appPort,
AppProtocol: dapr.AppProtocol,
EnableApiLogging: dapr.EnableApiLogging,
HttpMaxRequestSize: dapr.DaprHttpMaxRequestSize,
HttpReadBufferSize: dapr.DaprHttpReadBufferSize,
LogLevel: dapr.LogLevel,
}
break
}
}
if err := b.buildEnvBlock(project.Env, &projectTemplateCtx); err != nil {
return err
}
if err := b.buildArgsBlock(project.Args, &projectTemplateCtx); err != nil {
return err
}
if err := b.buildDeployBlock(project.DeploymentParams, &projectTemplateCtx); err != nil {
return err
}
b.containerAppTemplateContexts[resourceName] = projectTemplateCtx
}
for moduleName, module := range b.bicepContext.BicepModules {
for paramName, paramValue := range module.Params {
value, err := b.resolveBicepReference(paramValue)
if err != nil {
return fmt.Errorf(
"resolving bicep module %s, param: %s, reference %s: %w", moduleName, paramName, paramValue, err)
}
module.Params[paramName] = value
}
if module.Scope != defaultBicepModuleScope {
rgScope := "resourceGroup"
if matches := resourceValueOnlyRefRegex.FindStringSubmatch(module.Scope); len(matches) == 2 {
manifestResourceName := matches[1]
// Check if the scope is an input
input, hasInput := b.bicepContext.InputParameters[manifestResourceName]
if hasInput {
input.scope = &rgScope
b.bicepContext.InputParameters[manifestResourceName] = input
}
}
scope, err := b.resolveBicepReference(module.Scope)
if err != nil {
return fmt.Errorf("resolving bicep module %s scope %s: %w", moduleName, module.Scope, err)
}
scope = fmt.Sprintf("%s(%s)", rgScope, scope)
module.Scope = scope
}
b.bicepContext.BicepModules[moduleName] = module
}
for _, kv := range b.bicepContext.KeyVaults {
if kv.ReadAccessPrincipalId {
b.bicepContext.RequiresPrincipalId = true
break
}
}
return nil
}