Skip to content

Commit d5f2924

Browse files
authored
[App Service] functionapp create: Check if storage account is network restricted (#30605)
1 parent 5814523 commit d5f2924

File tree

90 files changed

+51047
-23622
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+51047
-23622
lines changed

src/azure-cli/azure/cli/command_modules/appservice/_params.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,8 @@ def load_arguments(self, _):
828828
"string. For the system assigned managed-identity authentication type, this parameter is not applicable and should be left empty.", is_preview=True)
829829
c.argument('zone_redundant', arg_type=get_three_state_flag(),
830830
help='Enable zone redundancy for high availability. Applies to Flex Consumption SKU only.', is_preview=True)
831+
c.argument('configure_networking_later', options_list=['--configure-networking-later', '--cnl'], arg_type=get_three_state_flag(),
832+
help='Use this option if you want to configure networking later for an app using network-restricted storage.')
831833

832834
with self.argument_context('functionapp deployment config set') as c:
833835
c.argument('deployment_storage_name', options_list=['--deployment-storage-name', '--dsn'], help="The deployment storage account name.", is_preview=True)

src/azure-cli/azure/cli/command_modules/appservice/custom.py

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4775,7 +4775,7 @@ def create_functionapp(cmd, resource_group_name, name, storage_account, plan=Non
47754775
always_ready_instances=None, maximum_instance_count=None, instance_memory=None,
47764776
flexconsumption_location=None, deployment_storage_name=None,
47774777
deployment_storage_container_name=None, deployment_storage_auth_type=None,
4778-
deployment_storage_auth_value=None, zone_redundant=False):
4778+
deployment_storage_auth_value=None, zone_redundant=False, configure_networking_later=None):
47794779
# pylint: disable=too-many-statements, too-many-branches
47804780

47814781
if functions_version is None and flexconsumption_location is None:
@@ -4992,6 +4992,22 @@ def create_functionapp(cmd, resource_group_name, name, storage_account, plan=Non
49924992
else SiteConfigPropertiesDictionary()
49934993
app_settings_dict = matched_runtime.app_settings_dict if not flexconsumption_location else {}
49944994

4995+
if is_storage_account_network_restricted(cmd.cli_ctx, resource_group_name, storage_account):
4996+
if consumption_plan_location is not None:
4997+
raise ValidationError('The Consumption plan does not support storage accounts with network restrictions. '
4998+
'If you wish to use virtual networks, please create your app on a different hosting '
4999+
'plan.')
5000+
5001+
if not vnet and not configure_networking_later:
5002+
raise ValidationError('The storage account you selected "{}" has networking restrictions. No virtual '
5003+
'networking was configured so your app will not start. Please try again with '
5004+
'virtual networking integration by adding the --vnet and --subnet flags. If '
5005+
'you wish to do this at a later time, use the --configure-networking-later '
5006+
'flag instead.'.format(storage_account))
5007+
if vnet and configure_networking_later:
5008+
raise ValidationError('The --vnet and --configure-networking-later flags are mutually exclusive.')
5009+
functionapp_def.vnet_content_share_enabled = True
5010+
49955011
con_string = _validate_and_get_connection_string(cmd.cli_ctx, resource_group_name, storage_account)
49965012

49975013
if environment is not None:
@@ -5130,7 +5146,10 @@ def create_functionapp(cmd, resource_group_name, name, storage_account, plan=Non
51305146
if (plan_info is not None and is_plan_elastic_premium(cmd, plan_info)) or consumption_plan_location is not None:
51315147
site_config.app_settings.append(NameValuePair(name='WEBSITE_CONTENTAZUREFILECONNECTIONSTRING',
51325148
value=con_string))
5133-
site_config.app_settings.append(NameValuePair(name='WEBSITE_CONTENTSHARE', value=_get_content_share_name(name)))
5149+
content_share_name = _get_content_share_name(name)
5150+
site_config.app_settings.append(NameValuePair(name='WEBSITE_CONTENTSHARE', value=content_share_name))
5151+
if is_storage_account_network_restricted(cmd.cli_ctx, resource_group_name, storage_account):
5152+
create_file_share(cmd.cli_ctx, resource_group_name, storage_account, content_share_name)
51345153

51355154
create_app_insights = False
51365155

@@ -5359,6 +5378,16 @@ def _validate_cpu_momory_functionapp(cpu=None, memory=None):
53595378
return
53605379

53615380

5381+
def create_file_share(cli_ctx, resource_group_name, storage_account, share_name):
5382+
5383+
storage_client = get_mgmt_service_client(cli_ctx, StorageManagementClient)
5384+
from azure.mgmt.storage.models import FileShare
5385+
5386+
file_share = FileShare()
5387+
5388+
return storage_client.file_shares.create(resource_group_name, storage_account, share_name, file_share=file_share)
5389+
5390+
53625391
def _get_extension_version_functionapp(functions_version):
53635392
if functions_version is not None:
53645393
return '~{}'.format(functions_version)
@@ -5705,6 +5734,19 @@ def _validate_and_get_connection_string(cli_ctx, resource_group_name, storage_ac
57055734
return connection_string
57065735

57075736

5737+
def is_storage_account_network_restricted(cli_ctx, resource_group_name, storage_account):
5738+
sa_resource_group = resource_group_name
5739+
if is_valid_resource_id(storage_account):
5740+
sa_resource_group = parse_resource_id(storage_account)['resource_group']
5741+
storage_account = parse_resource_id(storage_account)['name']
5742+
storage_client = get_mgmt_service_client(cli_ctx, StorageManagementClient)
5743+
storage_properties = storage_client.storage_accounts.get_properties(sa_resource_group,
5744+
storage_account)
5745+
return storage_properties.public_network_access == 'Disabled' or \
5746+
(storage_properties.public_network_access == 'Enabled' and
5747+
storage_properties.network_rule_set.default_action == 'Deny')
5748+
5749+
57085750
def list_consumption_locations(cmd):
57095751
client = web_client_factory(cmd.cli_ctx)
57105752
regions = client.list_geo_regions(sku='Dynamic')

src/azure-cli/azure/cli/command_modules/appservice/tests/latest/recordings/test_acr_create_function_app.yaml

Lines changed: 1172 additions & 1178 deletions
Large diffs are not rendered by default.

src/azure-cli/azure/cli/command_modules/appservice/tests/latest/recordings/test_acr_deployment_function_app.yaml

Lines changed: 1334 additions & 736 deletions
Large diffs are not rendered by default.

src/azure-cli/azure/cli/command_modules/appservice/tests/latest/recordings/test_acr_integration_function_app.yaml

Lines changed: 1229 additions & 1074 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)