func()

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
}