Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

from ._validators import (validate_timeout_value, validate_site_create, validate_asp_create,
validate_ase_create, validate_ip_address,
validate_service_tag, validate_public_cloud)
validate_service_tag, validate_public_cloud, warn_linux_consumption_eol)

AUTH_TYPES = {
'AllowAnonymous': 'na',
Expand Down Expand Up @@ -94,6 +94,14 @@ def load_arguments(self, _):
help="the name of the slot. Default to the productions slot if not specified")
c.argument('name', arg_type=webapp_name_arg_type)

with self.argument_context('functionapp') as c:
c.ignore('app_instance')
c.argument('resource_group_name', arg_type=resource_group_name_type)
c.argument('location', arg_type=get_location_type(self.cli_ctx))
c.argument('slot', options_list=['--slot', '-s'],
help="the name of the slot. Default to the productions slot if not specified")
c.argument('name', arg_type=functionapp_name_arg_type, validator=warn_linux_consumption_eol)
Comment on lines +97 to +103

with self.argument_context('appservice') as c:
c.argument('resource_group_name', arg_type=resource_group_name_type)
c.argument('location', arg_type=get_location_type(self.cli_ctx))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ def validate_functionapp_on_containerapp_site_config_set(cmd, namespace):
raise ValidationError(
"Invalid command. This is not supported for Azure Functions on Azure Container app environments.",
"Please use the following command instead: az functionapp config container set")
warn_linux_consumption_eol(cmd, namespace)


def validate_functionapp_on_containerapp_container_settings_delete(cmd, namespace):
Expand All @@ -162,6 +163,7 @@ def validate_functionapp_on_containerapp_update(cmd, namespace):
raise ValidationError(
"Invalid command. This is currently not supported for Azure Functions on Azure Container app environments.",
"Please use either 'az functionapp config appsettings set' or 'az functionapp config container set'")
warn_linux_consumption_eol(cmd, namespace)


def validate_functionapp_on_containerapp_site_config_show(cmd, namespace):
Expand All @@ -171,6 +173,7 @@ def validate_functionapp_on_containerapp_site_config_show(cmd, namespace):
raise ValidationError(
"Invalid command. This is not supported for Azure Functions on Azure Container app environments.",
"Please use the following command instead: az functionapp config container show")
warn_linux_consumption_eol(cmd, namespace)


def validate_functionapp_on_flex_plan(cmd, namespace):
Expand Down Expand Up @@ -206,6 +209,52 @@ def validate_is_flex_functionapp(cmd, namespace):
raise ValidationError('This command is only valid for Azure Functions on the FlexConsumption plan.')


def warn_linux_consumption_eol(cmd, namespace):
"""Shows a warning if the function app is on Linux Consumption plan."""
from azure.core.exceptions import ResourceNotFoundError as ResNotFoundError, HttpResponseError

resource_group_name = getattr(namespace, 'resource_group_name', None) or getattr(namespace, 'resource_group', None)
name = _get_app_name(namespace)
slot = getattr(namespace, 'slot', None)
if not name or not resource_group_name:
return

functionapp = None
try:
functionapp = _generic_site_operation(cmd.cli_ctx, resource_group_name, name, 'get', slot)
except (ResNotFoundError, HttpResponseError):
# App doesn't exist yet (e.g., during create command) or is inaccessible, skip warning
pass
if functionapp is None:
return

# Check if Linux (reserved=True) and get the plan
is_linux = getattr(functionapp, 'reserved', False)
server_farm_id = get_site_server_farm_id(functionapp)
if not is_linux or server_farm_id is None:
return

parsed_plan_id = parse_resource_id(server_farm_id)
client = web_client_factory(cmd.cli_ctx)
plan_info = None
try:
plan_info = client.app_service_plans.get(parsed_plan_id['resource_group'], parsed_plan_id['name'])
except (ResNotFoundError, HttpResponseError):
# Plan not found or inaccessible, skip warning
pass
if plan_info is None or not hasattr(plan_info, 'sku') or plan_info.sku is None:
return

if plan_info.sku.tier == 'Dynamic':
logger.warning(
"Migrate your app to Flex Consumption as Linux Consumption will reach EOL on "
"September 30, 2028 and will no longer be supported. Flex Consumption is now the "
"recommended serverless hosting plan for Azure Functions. It offers faster scaling, "
"reduced cold starts, private networking, and more control over performance and cost. Help link: "
"https://learn.microsoft.com/en-us/azure/azure-functions/migration/migrate-plan-consumption-to-flex"
)


def validate_app_exists(cmd, namespace):
app = namespace.name
resource_group_name = namespace.resource_group_name
Expand All @@ -227,6 +276,7 @@ def validate_functionapp_on_containerapp_vnet(cmd, namespace):
raise ValidationError(
'Unsupported operation on function app.',
'Please set virtual network configuration for the function app at Container app environment level.')
warn_linux_consumption_eol(cmd, namespace)


def validate_add_vnet(cmd, namespace):
Expand Down Expand Up @@ -629,6 +679,7 @@ def validate_app_is_functionapp(cmd, namespace):
raise ValidationError(f"App '{name}' in group '{rg}' is a logic app.")
if is_webapp(app):
raise ValidationError(f"App '{name}' in group '{rg}' is a web app.")
warn_linux_consumption_eol(cmd, namespace)


def validate_centauri_delete_function(cmd, namespace):
Expand All @@ -638,6 +689,7 @@ def validate_centauri_delete_function(cmd, namespace):
raise ValidationError(
"Invalid Operation. This function is currently present in your image",
"Please modify your image to remove the function and provide an updated image.")
warn_linux_consumption_eol(cmd, namespace)


def validate_registry_server(namespace):
Expand Down
22 changes: 22 additions & 0 deletions src/azure-cli/azure/cli/command_modules/appservice/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -8624,6 +8624,28 @@ def create_functionapp(cmd, resource_group_name, name, storage_account, plan=Non
raise ValidationError("Location is invalid. Use: az functionapp list-flexconsumption-locations")
is_linux = True

# Show warnings for Consumption plan (Linux or Windows)
# Check if using --consumption-plan-location OR --plan with a consumption SKU (Dynamic tier)
plan_sku = getattr(plan_info, 'sku', None) if plan_info else None
plan_sku_tier = getattr(plan_sku, 'tier', None)
is_consumption_plan = consumption_plan_location is not None or (plan_info and plan_sku_tier == 'Dynamic')
if is_consumption_plan:
if is_linux:
logger.warning(
"Linux Consumption will reach EOL on September 30, 2028 and will no longer be supported. "
"Flex Consumption is now the recommended serverless hosting plan for Azure Functions. "
"It offers faster scaling, reduced cold starts, private networking, and more control over "
"performance and cost. Help link: "
"https://learn.microsoft.com/en-us/azure/azure-functions/migration/migrate-plan-consumption-to-flex"
)
Comment thread
patelchandni marked this conversation as resolved.
else:
logger.warning(
"Flex Consumption is now the recommended serverless hosting plan for Azure Functions. "
"It offers faster scaling, reduced cold starts, private networking, and more control over "
"performance and cost. Help link: "
"https://learn.microsoft.com/en-us/azure/azure-functions/migration/migrate-plan-consumption-to-flex"
)

if environment is not None:
if consumption_plan_location is not None:
raise ArgumentUsageError(
Expand Down
Loading
Loading