def create_functionapp()

in src/azure-cli/azure/cli/command_modules/appservice/custom.py [0:0]


def create_functionapp(cmd, resource_group_name, name, storage_account, plan=None,
                       os_type=None, functions_version=None, runtime=None, runtime_version=None,
                       consumption_plan_location=None, app_insights=None, app_insights_key=None,
                       disable_app_insights=None, deployment_source_url=None,
                       deployment_source_branch=None, deployment_local_git=None,
                       registry_server=None, registry_password=None, registry_username=None,
                       image=None, tags=None, assign_identities=None,
                       role='Contributor', scope=None, vnet=None, subnet=None, https_only=False,
                       environment=None, min_replicas=None, max_replicas=None, workspace=None,
                       enable_dapr=False, dapr_app_id=None, dapr_app_port=None, dapr_http_max_request_size=None,
                       dapr_http_read_buffer_size=None, dapr_log_level=None, dapr_enable_api_logging=False,
                       workload_profile_name=None, cpu=None, memory=None,
                       always_ready_instances=None, maximum_instance_count=None, instance_memory=None,
                       flexconsumption_location=None, deployment_storage_name=None,
                       deployment_storage_container_name=None, deployment_storage_auth_type=None,
                       deployment_storage_auth_value=None, zone_redundant=False, configure_networking_later=None):
    # pylint: disable=too-many-statements, too-many-branches

    if functions_version is None and flexconsumption_location is None:
        logger.warning("No functions version specified so defaulting to 4.")
        functions_version = '4'
    enable_dapr = enable_dapr == "true"
    if deployment_source_url and deployment_local_git:
        raise MutuallyExclusiveArgumentError('usage error: --deployment-source-url <url> | --deployment-local-git')
    if any([cpu, memory, workload_profile_name]) and environment is None:
        raise RequiredArgumentMissingError("usage error: parameters --cpu, -memory, --workload-profile-name "
                                           "must be used with parameter --environment, please provide the "
                                           "name of the container app environment using --environment.")
    if environment is None and not is_exactly_one_true(plan, consumption_plan_location, flexconsumption_location):
        raise MutuallyExclusiveArgumentError("usage error: You must specify one of these parameter "
                                             "--plan NAME_OR_ID | --consumption-plan-location LOCATION |"
                                             " --flexconsumption-location LOCATION")

    if ((min_replicas is not None or max_replicas is not None) and environment is None):
        raise RequiredArgumentMissingError("usage error: parameters --min-replicas and --max-replicas must be "
                                           "used with parameter --environment, please provide the name "
                                           "of the container app environment using --environment.")
    if any([enable_dapr, dapr_app_id, dapr_app_port, dapr_http_max_request_size, dapr_http_read_buffer_size,
            dapr_log_level, dapr_enable_api_logging]) and environment is None:
        raise RequiredArgumentMissingError("usage error: parameters --enable-dapr, --dapr-app-id, "
                                           "--dapr-app-port, --dapr-http-max-request-size, "
                                           "--dapr-http-read-buffer-size, --dapr-log-level and "
                                           "dapr-enable-api-logging must be used with parameter --environment,"
                                           "please provide the name of the container app environment using "
                                           "--environment.")
    if any([dapr_app_id, dapr_app_port, dapr_http_max_request_size, dapr_http_read_buffer_size,
            dapr_log_level, dapr_enable_api_logging]) and not enable_dapr:
        raise ArgumentUsageError("usage error: parameters --dapr-app-id, "
                                 "--dapr-app-port, --dapr-http-max-request-size, "
                                 "--dapr-http-read-buffer-size, --dapr-log-level and "
                                 "dapr-enable-api-logging must be used with parameter --enable-dapr true.")

    from azure.mgmt.web.models import Site
    SiteConfig, NameValuePair, DaprConfig, ResourceConfig = cmd.get_models('SiteConfig', 'NameValuePair',
                                                                           'DaprConfig', 'ResourceConfig')

    if flexconsumption_location is None:
        if zone_redundant:
            raise ArgumentUsageError(
                '--zone-redundant is only valid for the Flex Consumption plan. '
                'Please try again without the --zone-redundant parameter.')

    if flexconsumption_location is not None:
        if image is not None:
            raise ArgumentUsageError(
                '--image is not a valid input for Azure Functions on the Flex Consumption plan. '
                'Please try again without the --image parameter.')

        if deployment_local_git is not None:
            raise ArgumentUsageError(
                '--deployment-local-git is not a valid input for Azure Functions on the Flex Consumption plan. '
                'Please try again without the --deployment-local-git parameter.')

        if deployment_source_url is not None:
            raise ArgumentUsageError(
                '--deployment-source-url is not a valid input for Azure Functions on the Flex Consumption plan. '
                'Please try again without the --deployment-source-url parameter.')

        if deployment_source_branch is not None:
            raise ArgumentUsageError(
                '--deployment-source-branch is not a valid input for Azure Functions on the Flex Consumption plan. '
                'Please try again without the --deployment-source-branch parameter.')

        if os_type and os_type.lower() != LINUX_OS_NAME:
            raise ArgumentUsageError(
                '--os-type windows is not a valid input for Azure Functions on the Flex Consumption plan. '
                'Please try again without the --os-type parameter or set --os-type to be linux.'
            )

        flexconsumption_location = _normalize_flex_location(flexconsumption_location)

    if (any([always_ready_instances, maximum_instance_count, instance_memory, deployment_storage_name,
            deployment_storage_container_name, deployment_storage_auth_type, deployment_storage_auth_value]) and
            flexconsumption_location is None):
        raise RequiredArgumentMissingError("usage error: parameters --always-ready-instances, "
                                           "--maximum-instance-count, --instance-memory, "
                                           "--deployment-storage-name, --deployment-storage-container-name, "
                                           "--deployment-storage-auth-type and --deployment-storage-auth-value "
                                           "must be used with parameter --flexconsumption-location, please "
                                           "provide the name of the flex plan location using "
                                           "--flexconsumption-location.")

    if flexconsumption_location is None:
        deployment_source_branch = deployment_source_branch or 'master'

    disable_app_insights = disable_app_insights == "true"

    site_config = SiteConfig(app_settings=[])
    client = web_client_factory(cmd.cli_ctx)

    if vnet or subnet:
        if plan:
            if is_valid_resource_id(plan):
                parse_result = parse_resource_id(plan)
                plan_info = client.app_service_plans.get(parse_result['resource_group'], parse_result['name'])
            else:
                plan_info = client.app_service_plans.get(resource_group_name, plan)
            webapp_location = plan_info.location
        elif flexconsumption_location:
            webapp_location = flexconsumption_location
            register_app_provider(cmd)
        else:
            webapp_location = consumption_plan_location

        subnet_info = _get_subnet_info(cmd=cmd,
                                       resource_group_name=resource_group_name,
                                       subnet=subnet,
                                       vnet=vnet)
        _validate_vnet_integration_location(cmd=cmd, webapp_location=webapp_location,
                                            subnet_resource_group=subnet_info["resource_group_name"],
                                            vnet_name=subnet_info["vnet_name"],
                                            vnet_sub_id=subnet_info["subnet_subscription_id"])
        _vnet_delegation_check(cmd, subnet_subscription_id=subnet_info["subnet_subscription_id"],
                               vnet_resource_group=subnet_info["resource_group_name"],
                               vnet_name=subnet_info["vnet_name"],
                               subnet_name=subnet_info["subnet_name"],
                               subnet_service_delegation=FLEX_SUBNET_DELEGATION if flexconsumption_location else None)
        subnet_resource_id = subnet_info["subnet_resource_id"]
        vnet_route_all_enabled = True
        site_config.vnet_route_all_enabled = True
    else:
        subnet_resource_id = None
        vnet_route_all_enabled = None

    functionapp_def = Site(location=None, site_config=site_config, tags=tags,
                           virtual_network_subnet_id=subnet_resource_id, https_only=https_only,
                           vnet_route_all_enabled=vnet_route_all_enabled)

    plan_info = None
    if runtime is not None:
        runtime = runtime.lower()

    is_storage_container_created = False
    is_user_assigned_identity_created = False

    if consumption_plan_location:
        locations = list_consumption_locations(cmd)
        location = next((loc for loc in locations if loc['name'].lower() == consumption_plan_location.lower()), None)
        if location is None:
            raise ValidationError("Location is invalid. Use: az functionapp list-consumption-locations")
        functionapp_def.location = consumption_plan_location
        functionapp_def.kind = 'functionapp'
        # if os_type is None, the os type is windows
        is_linux = bool(os_type and os_type.lower() == LINUX_OS_NAME)

    elif plan:  # apps with SKU based plan
        if is_valid_resource_id(plan):
            parse_result = parse_resource_id(plan)
            plan_info = client.app_service_plans.get(parse_result['resource_group'], parse_result['name'])
        else:
            plan_info = client.app_service_plans.get(resource_group_name, plan)
        if not plan_info:
            raise ResourceNotFoundError("The plan '{}' doesn't exist".format(plan))
        location = plan_info.location
        is_linux = bool(plan_info.reserved)
        functionapp_def.server_farm_id = plan
        functionapp_def.location = location

    elif flexconsumption_location:
        locations = list_flexconsumption_locations(cmd)
        location = next((loc for loc in locations if loc['name'].lower() == flexconsumption_location.lower()), None)
        if location is None:
            raise ValidationError("Location is invalid. Use: az functionapp list-flexconsumption-locations")
        is_linux = True

    if environment is not None:
        if consumption_plan_location is not None:
            raise ArgumentUsageError(
                '--consumption-plan-location is not a valid input for Azure Functions on Azure Container App '
                'environments. Please try again without the --consumption-plan-location parameter.')

        if plan is not None:
            raise ArgumentUsageError(
                '--plan is not a valid input for Azure Functions on Azure Container App environments. '
                'Please try again without the --plan parameter.')

        if os_type is not None:
            raise ArgumentUsageError(
                '--os-type is not a valid input for Azure Functions on Azure Container App environments. '
                'Please try again without the --os-type parameter.')

        is_linux = True

        if image is None:
            image = DEFAULT_CENTAURI_IMAGE

    if registry_server:
        docker_registry_server_url = registry_server
    else:
        docker_registry_server_url = parse_docker_image_name(image, environment)

    if is_linux and not runtime and (consumption_plan_location or not image):
        raise ArgumentUsageError(
            "usage error: --runtime RUNTIME required for linux functions apps without custom image.")

    if runtime is None and runtime_version is not None:
        raise ArgumentUsageError('Must specify --runtime to use --runtime-version')

    if flexconsumption_location:
        runtime_helper = _FlexFunctionAppStackRuntimeHelper(cmd, flexconsumption_location, runtime, runtime_version)
        matched_runtime = runtime_helper.resolve(runtime, runtime_version)
    else:
        runtime_helper = _FunctionAppStackRuntimeHelper(cmd, linux=is_linux, windows=not is_linux)
        matched_runtime = runtime_helper.resolve("dotnet" if not runtime else runtime,
                                                 runtime_version, functions_version, is_linux)

    SiteConfigPropertiesDictionary = cmd.get_models('SiteConfigPropertiesDictionary')

    site_config_dict = matched_runtime.site_config_dict if not flexconsumption_location \
        else SiteConfigPropertiesDictionary()
    app_settings_dict = matched_runtime.app_settings_dict if not flexconsumption_location else {}

    if is_storage_account_network_restricted(cmd.cli_ctx, resource_group_name, storage_account):
        if consumption_plan_location is not None:
            raise ValidationError('The Consumption plan does not support storage accounts with network restrictions. '
                                  'If you wish to use virtual networks, please create your app on a different hosting '
                                  'plan.')

        if not vnet and not configure_networking_later:
            raise ValidationError('The storage account you selected "{}" has networking restrictions. No virtual '
                                  'networking was configured so your app will not start. Please try again with '
                                  'virtual networking integration by adding the --vnet and --subnet flags. If '
                                  'you wish to do this at a later time, use the --configure-networking-later '
                                  'flag instead.'.format(storage_account))
        if vnet and configure_networking_later:
            raise ValidationError('The --vnet and --configure-networking-later flags are mutually exclusive.')
        functionapp_def.vnet_content_share_enabled = True

    con_string = _validate_and_get_connection_string(cmd.cli_ctx, resource_group_name, storage_account)

    if environment is not None:
        if docker_registry_server_url is not None:
            site_config.app_settings.append(
                NameValuePair(name='DOCKER_REGISTRY_SERVER_URL', value=docker_registry_server_url)
            )

        if (not registry_username and not registry_password and
                docker_registry_server_url and '.azurecr.io' in str(docker_registry_server_url)):
            logger.warning('No credential was provided to access Azure Container Registry. Trying to look up...')
            parsed = urlparse(docker_registry_server_url)
            registry_name = (parsed.netloc if parsed.scheme else parsed.path).split('.')[0]
            try:
                registry_username, registry_password = _get_acr_cred(cmd.cli_ctx, registry_name)
            except Exception as ex:  # pylint: disable=broad-except
                logger.warning("Retrieving credentials failed with an exception:'%s'", ex)  # consider throw if needed

        if registry_username is not None:
            site_config.app_settings.append(
                NameValuePair(name='DOCKER_REGISTRY_SERVER_USERNAME', value=registry_username)
            )
        if registry_password is not None:
            site_config.app_settings.append(
                NameValuePair(name='DOCKER_REGISTRY_SERVER_PASSWORD', value=registry_password)
            )

        app_settings_dict = {}
        matched_runtime.app_insights = True
    elif is_linux:
        functionapp_def.kind = 'functionapp,linux'
        functionapp_def.reserved = True
        is_consumption = consumption_plan_location is not None or flexconsumption_location is not None
        if not is_consumption:
            site_config.app_settings.append(NameValuePair(name='MACHINEKEY_DecryptionKey',
                                                          value=str(hexlify(urandom(32)).decode()).upper()))
            if image:
                functionapp_def.kind = 'functionapp,linux,container'
                site_config.app_settings.append(NameValuePair(name='DOCKER_CUSTOM_IMAGE_NAME',
                                                              value=image))
                site_config.app_settings.append(NameValuePair(name='FUNCTION_APP_EDIT_MODE', value='readOnly'))
                site_config.app_settings.append(NameValuePair(name='WEBSITES_ENABLE_APP_SERVICE_STORAGE',
                                                              value='false'))
                site_config.linux_fx_version = _format_fx_version(image)

                # clear all runtime specific configs and settings
                site_config_dict.use32_bit_worker_process = False
                app_settings_dict = {}

                # ensure that app insights is created if not disabled
                matched_runtime.app_insights = True
            else:
                site_config.app_settings.append(NameValuePair(name='WEBSITES_ENABLE_APP_SERVICE_STORAGE',
                                                              value='true'))
    else:
        functionapp_def.kind = 'functionapp'

    if site_config_dict.additional_properties:
        for prop, value in site_config_dict.additional_properties.items():
            snake_case_prop = _convert_camel_to_snake_case(prop)
            setattr(site_config, snake_case_prop, value)

    # set site configs
    for prop, value in site_config_dict.as_dict().items():
        snake_case_prop = _convert_camel_to_snake_case(prop)
        setattr(site_config, snake_case_prop, value)

    if environment is not None:
        functionapp_def.kind = 'functionapp,linux,container,azurecontainerapps'
        functionapp_def.reserved = None
        functionapp_def.name = name
        functionapp_def.https_only = None
        functionapp_def.scm_site_also_stopped = None
        functionapp_def.hyper_v = None
        functionapp_def.is_xenon = None
        functionapp_def.type = 'Microsoft.Web/sites'

        # validate cpu and memory parameters.
        _validate_cpu_momory_functionapp(cpu, memory)

        if workload_profile_name is not None:
            functionapp_def.workload_profile_name = workload_profile_name

        if cpu is not None and memory is not None:
            functionapp_def.resource_config = ResourceConfig()
            functionapp_def.resource_config.cpu = cpu
            functionapp_def.resource_config.memory = memory

        site_config.net_framework_version = None
        site_config.java_version = None
        site_config.use32_bit_worker_process = None
        site_config.power_shell_version = None
        site_config.linux_fx_version = _format_fx_version(image)
        site_config.http20_enabled = None
        site_config.local_my_sql_enabled = None
        if min_replicas is not None:
            site_config.minimum_elastic_instance_count = min_replicas
        if max_replicas is not None:
            site_config.function_app_scale_limit = max_replicas

        if enable_dapr:
            logger.warning("Please note while using Dapr Extension for Azure Functions, app port is "
                           "mandatory when using Dapr triggers and should be empty when using only Dapr bindings.")
            dapr_enable_api_logging = dapr_enable_api_logging == "true"
            dapr_config = DaprConfig()
            dapr_config.enabled = True
            dapr_config.app_id = dapr_app_id
            dapr_config.app_port = dapr_app_port
            dapr_config.http_max_request_size = dapr_http_max_request_size or 4
            dapr_config.http_read_buffer_size = dapr_http_read_buffer_size or 4
            dapr_config.log_level = dapr_log_level
            dapr_config.enable_api_logging = dapr_enable_api_logging
            functionapp_def.dapr_config = dapr_config

        managed_environment = get_managed_environment(cmd, resource_group_name, environment)
        location = managed_environment.location
        functionapp_def.location = location

        functionapp_def.managed_environment_id = managed_environment.id

    # adding app settings
    for app_setting, value in app_settings_dict.items():
        site_config.app_settings.append(NameValuePair(name=app_setting, value=value))

    if flexconsumption_location is None:
        site_config.app_settings.append(NameValuePair(name='FUNCTIONS_EXTENSION_VERSION',
                                                      value=_get_extension_version_functionapp(functions_version)))
    site_config.app_settings.append(NameValuePair(name='AzureWebJobsStorage', value=con_string))

    # If plan is not flex, consumption or elastic premium, we need to set always on
    if (flexconsumption_location is None and consumption_plan_location is None and plan_info is not None and
            not is_plan_elastic_premium(cmd, plan_info)):
        site_config.always_on = True

    # If plan is elastic premium or consumption, we need these app settings
    if (plan_info is not None and is_plan_elastic_premium(cmd, plan_info)) or consumption_plan_location is not None:
        site_config.app_settings.append(NameValuePair(name='WEBSITE_CONTENTAZUREFILECONNECTIONSTRING',
                                                      value=con_string))
        content_share_name = _get_content_share_name(name)
        site_config.app_settings.append(NameValuePair(name='WEBSITE_CONTENTSHARE', value=content_share_name))
        if is_storage_account_network_restricted(cmd.cli_ctx, resource_group_name, storage_account):
            create_file_share(cmd.cli_ctx, resource_group_name, storage_account, content_share_name)

    create_app_insights = False

    if app_insights_key is not None:
        site_config.app_settings.append(NameValuePair(name='APPINSIGHTS_INSTRUMENTATIONKEY',
                                                      value=app_insights_key))
    elif app_insights is not None:
        app_insights_conn_string = get_app_insights_connection_string(cmd.cli_ctx, resource_group_name, app_insights)
        site_config.app_settings.append(NameValuePair(name='APPLICATIONINSIGHTS_CONNECTION_STRING',
                                                      value=app_insights_conn_string))
    elif flexconsumption_location is None and (disable_app_insights or not matched_runtime.app_insights):
        # set up dashboard if no app insights
        site_config.app_settings.append(NameValuePair(name='AzureWebJobsDashboard', value=con_string))
    elif not disable_app_insights and matched_runtime.app_insights:
        create_app_insights = True

    if flexconsumption_location is not None:
        if zone_redundant:
            zone_redundant_locations = list_flexconsumption_zone_redundant_locations(cmd)
            zone_redundant_location = next((loc for loc in zone_redundant_locations
                                            if loc['name'].lower() == flexconsumption_location.lower()), None)
            if zone_redundant_location is None:
                raise ValidationError("The specified location '{0}' "
                                      "doesn't support zone redundancy in Flex Consumption. "
                                      "Use: az functionapp list-flexconsumption-locations --zone-redundant "
                                      "for the list of locations that support zone redundancy."
                                      .format(flexconsumption_location))

        site_config.net_framework_version = None
        functionapp_def.reserved = None
        functionapp_def.is_xenon = None

        try:
            plan_name = generatePlanName(resource_group_name)
            plan_info = create_flex_app_service_plan(
                cmd, resource_group_name, plan_name, flexconsumption_location, zone_redundant)
            functionapp_def.server_farm_id = plan_info.id
            functionapp_def.location = flexconsumption_location

            if not deployment_storage_name:
                deployment_storage_name = storage_account
            deployment_storage = _validate_and_get_deployment_storage(cmd.cli_ctx, resource_group_name,
                                                                      deployment_storage_name)

            deployment_storage_container = _get_or_create_deployment_storage_container(
                cmd, resource_group_name, name, deployment_storage_name, deployment_storage_container_name)
            if deployment_storage_container_name is None:
                is_storage_container_created = True
            deployment_storage_container_name = deployment_storage_container.name

            endpoints = deployment_storage.primary_endpoints
            deployment_config_storage_value = getattr(endpoints, 'blob') + deployment_storage_container_name

            deployment_storage_auth_type = deployment_storage_auth_type or 'StorageAccountConnectionString'

            if deployment_storage_auth_value and deployment_storage_auth_type == 'SystemAssignedIdentity':
                raise ArgumentUsageError(
                    '--deployment-storage-auth-value is only a valid input when '
                    '--deployment-storage-auth-type is set to UserAssignedIdentity or StorageAccountConnectionString. '
                    'Please try again with --deployment-storage-auth-type set to UserAssignedIdentity or '
                    'StorageAccountConnectionString.'
                )

            function_app_config = {}
            deployment_storage_auth_config = {
                "type": deployment_storage_auth_type
            }
            function_app_config["deployment"] = {
                "storage": {
                    "type": "blobContainer",
                    "value": deployment_config_storage_value,
                    "authentication": deployment_storage_auth_config
                }
            }

            if deployment_storage_auth_type == 'UserAssignedIdentity':
                deployment_storage_user_assigned_identity = _get_or_create_user_assigned_identity(
                    cmd,
                    resource_group_name,
                    name,
                    deployment_storage_auth_value,
                    flexconsumption_location)
                if deployment_storage_auth_value is None:
                    is_user_assigned_identity_created = True
                deployment_storage_auth_value = deployment_storage_user_assigned_identity.id
                deployment_storage_auth_config["userAssignedIdentityResourceId"] = deployment_storage_auth_value
            elif deployment_storage_auth_type == 'StorageAccountConnectionString':
                deployment_storage_conn_string = _get_storage_connection_string(cmd.cli_ctx, deployment_storage)
                conn_string_app_setting = deployment_storage_auth_value or 'DEPLOYMENT_STORAGE_CONNECTION_STRING'
                site_config.app_settings.append(NameValuePair(name=conn_string_app_setting,
                                                              value=deployment_storage_conn_string))
                deployment_storage_auth_value = conn_string_app_setting
                deployment_storage_auth_config["storageAccountConnectionStringName"] = deployment_storage_auth_value

            flex_sku = matched_runtime.sku
            runtime = flex_sku['functionAppConfigProperties']['runtime']['name']
            version = flex_sku['functionAppConfigProperties']['runtime']['version']
            runtime_config = {
                "name": runtime,
                "version": version
            }
            function_app_config["runtime"] = runtime_config
            always_ready_dict = _parse_key_value_pairs(always_ready_instances)
            always_ready_config = []

            for key, value in always_ready_dict.items():
                always_ready_config.append(
                    {
                        "name": key,
                        "instanceCount": max(0, validate_and_convert_to_int(key, value))
                    }
                )

            default_instance_memory = [x for x in flex_sku['instanceMemoryMB'] if x['isDefault'] is True][0]

            function_app_config["scaleAndConcurrency"] = {
                "maximumInstanceCount": maximum_instance_count or flex_sku['maximumInstanceCount']['defaultValue'],
                "instanceMemoryMB": instance_memory or default_instance_memory['size'],
                "alwaysReady": always_ready_config
            }

            functionapp_def.enable_additional_properties_sending()
            existing_properties = functionapp_def.serialize()["properties"]
            functionapp_def.additional_properties["properties"] = existing_properties
            functionapp_def.additional_properties["properties"]["functionAppConfig"] = function_app_config
            functionapp_def.additional_properties["properties"]["sku"] = "FlexConsumption"
            poller = client.web_apps.begin_create_or_update(resource_group_name, name, functionapp_def,
                                                            api_version='2023-12-01')
            functionapp = LongRunningOperation(cmd.cli_ctx)(poller)
        except Exception as ex:  # pylint: disable=broad-except
            client.app_service_plans.delete(resource_group_name, plan_name)
            if is_storage_container_created:
                delete_storage_container(cmd, resource_group_name, deployment_storage_name,
                                         deployment_storage_container_name)
            if is_user_assigned_identity_created:
                delete_user_assigned_identity(cmd, resource_group_name, deployment_storage_user_assigned_identity.name)
            raise ex
    else:
        poller = client.web_apps.begin_create_or_update(resource_group_name, name, functionapp_def)
        functionapp = LongRunningOperation(cmd.cli_ctx)(poller)

    if environment is not None:
        functionapp = client.web_apps.get(resource_group_name, name)

    if consumption_plan_location and is_linux:
        logger.warning("Your Linux function app '%s', that uses a consumption plan has been successfully "
                       "created but is not active until content is published using "
                       "Azure Portal or the Functions Core Tools.", name)
    else:
        _set_remote_or_local_git(cmd, functionapp, resource_group_name, name, deployment_source_url,
                                 deployment_source_branch, deployment_local_git)

    if create_app_insights:
        try:
            try_create_workspace_based_application_insights(cmd, functionapp, workspace)
            if should_enable_distributed_tracing(consumption_plan_location,
                                                 flexconsumption_location,
                                                 matched_runtime,
                                                 image):
                update_app_settings(cmd, functionapp.resource_group, functionapp.name,
                                    ["APPLICATIONINSIGHTS_ENABLE_AGENT=true"])

        except Exception:  # pylint: disable=broad-except
            logger.warning('Error while trying to create and configure an Application Insights for the Function App. '
                           'Please use the Azure Portal to create and configure the Application Insights, if needed.')
            if flexconsumption_location is None:
                update_app_settings(cmd, functionapp.resource_group, functionapp.name,
                                    ['AzureWebJobsDashboard={}'.format(con_string)])

    if image and environment is None:
        update_container_settings_functionapp(cmd, resource_group_name, name, docker_registry_server_url,
                                              image, registry_username,
                                              registry_password)

    if flexconsumption_location is not None:
        if deployment_storage_auth_type == 'UserAssignedIdentity':
            assign_identity(cmd, resource_group_name, name, [deployment_storage_auth_value])
            if not _has_deployment_storage_role_assignment_on_resource(
                    cmd.cli_ctx,
                    deployment_storage,
                    deployment_storage_user_assigned_identity.principal_id):
                _assign_deployment_storage_managed_identity_role(
                    cmd.cli_ctx,
                    deployment_storage,
                    deployment_storage_user_assigned_identity.principal_id)
            else:
                logger.warning("User assigned identity '%s' already has the role assignment on "
                               "the storage account '%s'",
                               deployment_storage_user_assigned_identity.principal_id, deployment_storage_name)

        elif deployment_storage_auth_type == 'SystemAssignedIdentity':
            assign_identity(cmd, resource_group_name, name, ['[system]'], 'Storage Blob Data Contributor',
                            None, deployment_storage.id)

    if assign_identities is not None:
        identity = assign_identity(cmd, resource_group_name, name, assign_identities,
                                   role, None, scope)
        functionapp.identity = identity

    if flexconsumption_location is not None:
        return get_raw_functionapp(cmd.cli_ctx, resource_group_name, name)

    return functionapp