Skip to content

{AKS} az aks: add --outbound-type-sku for managed NAT Gateway V2 GA - #34017

Draft
Christine DOSSA (christine33-creator) wants to merge 2 commits into
Azure:devfrom
christine33-creator:cdossa/natgwv2-ga-cli-sku
Draft

{AKS} az aks: add --outbound-type-sku for managed NAT Gateway V2 GA#34017
Christine DOSSA (christine33-creator) wants to merge 2 commits into
Azure:devfrom
christine33-creator:cdossa/natgwv2-ga-cli-sku

Conversation

@christine33-creator

@christine33-creator Christine DOSSA (christine33-creator) commented Sep 2, 2026

Copy link
Copy Markdown

🤖 PR Validation — ❌ Action needed

Breaking Changes Tests
⚠️ None ❌ 128/130
⚠️AzureCLI-BreakingChangeTest
⚠️acs
rule cmd_name rule_message suggest_message
⚠️ 1006 - ParaAdd aks create cmd aks create added parameter nat_gateway_managed_outbound_ipv6_count
⚠️ 1006 - ParaAdd aks create cmd aks create added parameter nat_gateway_outbound_ip_ids
⚠️ 1006 - ParaAdd aks create cmd aks create added parameter nat_gateway_outbound_ip_prefix_ids
⚠️ 1006 - ParaAdd aks create cmd aks create added parameter nat_gateway_sku
⚠️ 1006 - ParaAdd aks update cmd aks update added parameter nat_gateway_managed_outbound_ipv6_count
⚠️ 1006 - ParaAdd aks update cmd aks update added parameter nat_gateway_outbound_ip_ids
⚠️ 1006 - ParaAdd aks update cmd aks update added parameter nat_gateway_outbound_ip_prefix_ids
⚠️ 1006 - ParaAdd aks update cmd aks update added parameter nat_gateway_sku
❌AzureCLI-FullTest
️✔️acr
️✔️latest
️✔️3.12
️✔️3.14
❌acs
❌latest
❌3.12
Type Test Case Error Message Line
Failed test_aks_create_and_update_with_managed_nat_gateway_v2 self = <azure.cli.testsdk.base.ExecutionResult object at 0x7fe2bbf836e0>
cli_ctx = <azure.cli.core.mock.DummyCli object at 0x7fe2bdee11f0>
command = 'group create --location westus2 --name clitestdwt5bad2t5 --tag product=azurecli cause=automation test date=2026-09-02T03:05:36Z test=test_aks_create_and_update_with_managed_nat_gateway_v2 module=acs'
expect_failure = False

    def in_process_execute(self, cli_ctx, command, expect_failure=False):
        from io import StringIO
        from vcr.errors import CannotOverwriteExistingCassetteException
    
        if command.startswith('az '):
            command = command[3:]
    
        stdout_buf = StringIO()
        logging_buf = StringIO()
        try:
            # issue: stderr cannot be redirect in this form, as a result some failure information
            # is lost when command fails.
>           self.exit_code = cli_ctx.invoke(shlex.split(command), out_file=stdout_buf) or 0
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

src/azure-cli-testsdk/azure/cli/testsdk/base.py:303: 
                                        
env/lib/python3.12/site-packages/knack/cli.py:245: in invoke
    exit_code = self.exception_handler(ex)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/init.py:153: in exception_handler
    return handle_exception(ex)
           ^^^^^^^^^^^^^^^^^^^^
                                        

ex = CLIError("Please run 'az login' to setup account."), args = (), kwargs = {}

    def handle_main_exception(ex, *args, **kwargs):  # pylint: disable=unused-argument
        if isinstance(ex, CannotOverwriteExistingCassetteException):
            # This exception usually caused by a no match HTTP request. This is a product error
            # that is caused by change of SDK invocation.
            raise ex
    
>       raise CliExecutionError(ex)
E       azure.cli.testsdk.exceptions.CliExecutionError: The CLI throws exception CLIError during execution and fails the command.

src/azure-cli-testsdk/azure/cli/testsdk/patches.py:35: CliExecutionError

During handling of the above exception, another exception occurred:
src/azure-cli-testsdk/azure/cli/testsdk/scenario_tests/decorators.py:40: in preparer_wrapper
    fn(test_class_instance, **kwargs)
src/azure-cli-testsdk/azure/cli/testsdk/scenario_tests/preparers.py:39: in preparer_wrapper
    parameter_update = self.create_resource(
src/azure-cli-testsdk/azure/cli/testsdk/preparers.py:99: in create_resource
    self.live_only_execute(self.cli_ctx, template.format(self.location, name))
src/azure-cli-testsdk/azure/cli/testsdk/preparers.py:39: in live_only_execute
    return self.raw_execute(cli_ctx, command, expect_failure)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-testsdk/azure/cli/testsdk/base.py:252: in init
    self.in_process_execute(cli_ctx, command, expect_failure=expect_failure)
src/azure-cli-testsdk/azure/cli/testsdk/base.py:315: in in_process_execute
    raise ex.exception
env/lib/python3.12/site-packages/knack/cli.py:233: in invoke
    cmd_result = self.invocation.execute(args)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:677: in execute
    raise ex
src/azure-cli-core/azure/cli/core/commands/init.py:820: in run_jobs_serially
    results.append(self.run_job(expanded_arg, cmd_copy))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:789: in run_job
    result = cmd_copy(params)
             ^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:335: in call
    return self.handler(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/command_operation.py:120: in handler
    return op(**command_args)
           ^^^^^^^^^^^^^^^^^^
src/azure-cli/azure/cli/command_modules/resource/custom.py:1642: in create_resource_group
    rcf = resource_client_factory(cmd.cli_ctx)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli/azure/cli/command_modules/resource/client_factory.py:10: in resource_client_factory
    return get_mgmt_service_client(cli_ctx, ResourceType.MGMT_RESOURCE_RESOURCES)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/client_factory.py:83: in get_mgmt_service_client
    client, 
 = get_mgmt_service_client(cli_ctx, client_type, subscription_id=subscription_id,
src/azure-cli-core/azure/cli/core/commands/client_factory.py:234: in get_mgmt_service_client
    credential, subscription_id, 
 = profile.get_login_credentials(
src/azure-cli-core/azure/cli/core/profile.py:342: in get_login_credentials
    account = self.get_subscription(subscription_id)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 
 
 
 
 
 
 
 
 
 
 
 
                           

self = <azure.cli.core._profile.Profile object at 0x7fe2ba31a360>
subscription = None

    def get_subscription(self, subscription=None):  # take id or name
        subscriptions = self.load_cached_subscriptions()
        if not subscriptions:
>           raise CLIError(_AZ_LOGIN_MESSAGE)
E           knack.util.CLIError: Please run 'az login' to setup account.

src/azure-cli-core/azure/cli/core/_profile.py:608: CLIError
azure/cli/command_modules/acs/tests/latest/test_aks_commands.py:1421
❌3.14
Type Test Case Error Message Line
Failed test_aks_create_and_update_with_managed_nat_gateway_v2 self = <azure.cli.testsdk.base.ExecutionResult object at 0x7fbc6d1134d0>
cli_ctx = <azure.cli.core.mock.DummyCli object at 0x7fbc70779a90>
command = 'group create --location westus2 --name clitestm4cn5x4t2b --tag product=azurecli cause=automation test date=2026-09-02T03:02:53Z test=test_aks_create_and_update_with_managed_nat_gateway_v2 module=acs'
expect_failure = False

    def in_process_execute(self, cli_ctx, command, expect_failure=False):
        from io import StringIO
        from vcr.errors import CannotOverwriteExistingCassetteException
    
        if command.startswith('az '):
            command = command[3:]
    
        stdout_buf = StringIO()
        logging_buf = StringIO()
        try:
            # issue: stderr cannot be redirect in this form, as a result some failure information
            # is lost when command fails.
>           self.exit_code = cli_ctx.invoke(shlex.split(command), out_file=stdout_buf) or 0
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

src/azure-cli-testsdk/azure/cli/testsdk/base.py:303: 
                                        
env/lib/python3.14/site-packages/knack/cli.py:245: in invoke
    exit_code = self.exception_handler(ex)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/init.py:153: in exception_handler
    return handle_exception(ex)
           ^^^^^^^^^^^^^^^^^^^^
                                        

ex = CLIError("Please run 'az login' to setup account."), args = (), kwargs = {}

    def handle_main_exception(ex, *args, **kwargs):  # pylint: disable=unused-argument
        if isinstance(ex, CannotOverwriteExistingCassetteException):
            # This exception usually caused by a no match HTTP request. This is a product error
            # that is caused by change of SDK invocation.
            raise ex
    
>       raise CliExecutionError(ex)
E       azure.cli.testsdk.exceptions.CliExecutionError: The CLI throws exception CLIError during execution and fails the command.

src/azure-cli-testsdk/azure/cli/testsdk/patches.py:35: CliExecutionError

During handling of the above exception, another exception occurred:
src/azure-cli-testsdk/azure/cli/testsdk/scenario_tests/decorators.py:40: in preparer_wrapper
    fn(test_class_instance, **kwargs)
src/azure-cli-testsdk/azure/cli/testsdk/scenario_tests/preparers.py:39: in preparer_wrapper
    parameter_update = self.create_resource(
src/azure-cli-testsdk/azure/cli/testsdk/preparers.py:99: in create_resource
    self.live_only_execute(self.cli_ctx, template.format(self.location, name))
src/azure-cli-testsdk/azure/cli/testsdk/preparers.py:39: in live_only_execute
    return self.raw_execute(cli_ctx, command, expect_failure)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-testsdk/azure/cli/testsdk/base.py:252: in init
    self.in_process_execute(cli_ctx, command, expect_failure=expect_failure)
src/azure-cli-testsdk/azure/cli/testsdk/base.py:315: in in_process_execute
    raise ex.exception
env/lib/python3.14/site-packages/knack/cli.py:233: in invoke
    cmd_result = self.invocation.execute(args)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:677: in execute
    raise ex
src/azure-cli-core/azure/cli/core/commands/init.py:820: in run_jobs_serially
    results.append(self.run_job(expanded_arg, cmd_copy))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:789: in run_job
    result = cmd_copy(params)
             ^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/init.py:335: in call
    return self.handler(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/command_operation.py:120: in handler
    return op(**command_args)
           ^^^^^^^^^^^^^^^^^^
src/azure-cli/azure/cli/command_modules/resource/custom.py:1642: in create_resource_group
    rcf = resource_client_factory(cmd.cli_ctx)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli/azure/cli/command_modules/resource/client_factory.py:10: in resource_client_factory
    return get_mgmt_service_client(cli_ctx, ResourceType.MGMT_RESOURCE_RESOURCES)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
src/azure-cli-core/azure/cli/core/commands/client_factory.py:83: in get_mgmt_service_client
    client, 
 = get_mgmt_service_client(cli_ctx, client_type, subscription_id=subscription_id,
src/azure-cli-core/azure/cli/core/commands/client_factory.py:234: in get_mgmt_service_client
    credential, subscription_id, 
 = profile.get_login_credentials(
src/azure-cli-core/azure/cli/core/profile.py:342: in get_login_credentials
    account = self.get_subscription(subscription_id)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 
 
 
 
 
 
 
 
 
 
 
 
                           

self = <azure.cli.core._profile.Profile object at 0x7fbc7848d940>
subscription = None

    def get_subscription(self, subscription=None):  # take id or name
        subscriptions = self.load_cached_subscriptions()
        if not subscriptions:
>           raise CLIError(_AZ_LOGIN_MESSAGE)
E           knack.util.CLIError: Please run 'az login' to setup account.

src/azure-cli-core/azure/cli/core/_profile.py:608: CLIError
azure/cli/command_modules/acs/tests/latest/test_aks_commands.py:1421
️✔️advisor
️✔️latest
️✔️3.12
️✔️3.14
️✔️ams
️✔️latest
️✔️3.12
️✔️3.14
️✔️apim
️✔️latest
️✔️3.12
️✔️3.14
️✔️appconfig
️✔️latest
️✔️3.12
️✔️3.14
️✔️appservice
️✔️latest
️✔️3.12
️✔️3.14
️✔️aro
️✔️latest
️✔️3.12
️✔️3.14
️✔️backup
️✔️latest
️✔️3.12
️✔️3.14
️✔️batch
️✔️latest
️✔️3.12
️✔️3.14
️✔️batchai
️✔️latest
️✔️3.12
️✔️3.14
️✔️billing
️✔️latest
️✔️3.12
️✔️3.14
️✔️botservice
️✔️latest
️✔️3.12
️✔️3.14
️✔️cloud
️✔️latest
️✔️3.12
️✔️3.14
️✔️cognitiveservices
️✔️latest
️✔️3.12
️✔️3.14
️✔️compute_recommender
️✔️latest
️✔️3.12
️✔️3.14
️✔️computefleet
️✔️latest
️✔️3.12
️✔️3.14
️✔️config
️✔️latest
️✔️3.12
️✔️3.14
️✔️configure
️✔️latest
️✔️3.12
️✔️3.14
️✔️consumption
️✔️latest
️✔️3.12
️✔️3.14
️✔️container
️✔️latest
️✔️3.12
️✔️3.14
️✔️containerapp
️✔️latest
️✔️3.12
️✔️3.14
️✔️core
️✔️latest
️✔️3.12
️✔️3.14
️✔️cosmosdb
️✔️latest
️✔️3.12
️✔️3.14
️✔️databoxedge
️✔️latest
️✔️3.12
️✔️3.14
️✔️dls
️✔️latest
️✔️3.12
️✔️3.14
️✔️dms
️✔️latest
️✔️3.12
️✔️3.14
️✔️eventgrid
️✔️latest
️✔️3.12
️✔️3.14
️✔️eventhubs
️✔️latest
️✔️3.12
️✔️3.14
️✔️feedback
️✔️latest
️✔️3.12
️✔️3.14
️✔️find
️✔️latest
️✔️3.12
️✔️3.14
️✔️hdinsight
️✔️latest
️✔️3.12
️✔️3.14
️✔️identity
️✔️latest
️✔️3.12
️✔️3.14
️✔️iot
️✔️latest
️✔️3.12
️✔️3.14
️✔️keyvault
️✔️latest
️✔️3.12
️✔️3.14
️✔️lab
️✔️latest
️✔️3.12
️✔️3.14
️✔️managedservices
️✔️latest
️✔️3.12
️✔️3.14
️✔️maps
️✔️latest
️✔️3.12
️✔️3.14
️✔️marketplaceordering
️✔️latest
️✔️3.12
️✔️3.14
️✔️monitor
️✔️latest
️✔️3.12
️✔️3.14
️✔️mysql
️✔️latest
️✔️3.12
️✔️3.14
️✔️netappfiles
️✔️latest
️✔️3.12
️✔️3.14
️✔️network
️✔️latest
️✔️3.12
️✔️3.14
️✔️policyinsights
️✔️latest
️✔️3.12
️✔️3.14
️✔️postgresql
️✔️latest
️✔️3.12
️✔️3.14
️✔️privatedns
️✔️latest
️✔️3.12
️✔️3.14
️✔️profile
️✔️latest
️✔️3.12
️✔️3.14
️✔️rdbms
️✔️latest
️✔️3.12
️✔️3.14
️✔️redis
️✔️latest
️✔️3.12
️✔️3.14
️✔️relay
️✔️latest
️✔️3.12
️✔️3.14
️✔️resource
️✔️latest
️✔️3.12
️✔️3.14
️✔️role
️✔️latest
️✔️3.12
️✔️3.14
️✔️search
️✔️latest
️✔️3.12
️✔️3.14
️✔️security
️✔️latest
️✔️3.12
️✔️3.14
️✔️servicebus
️✔️latest
️✔️3.12
️✔️3.14
️✔️serviceconnector
️✔️latest
️✔️3.12
️✔️3.14
️✔️servicefabric
️✔️latest
️✔️3.12
️✔️3.14
️✔️signalr
️✔️latest
️✔️3.12
️✔️3.14
️✔️sql
️✔️latest
️✔️3.12
️✔️3.14
️✔️sqlvm
️✔️latest
️✔️3.12
️✔️3.14
️✔️storage
️✔️latest
️✔️3.12
️✔️3.14
️✔️synapse
️✔️latest
️✔️3.12
️✔️3.14
️✔️telemetry
️✔️latest
️✔️3.12
️✔️3.14
️✔️util
️✔️latest
️✔️3.12
️✔️3.14
️✔️vm
️✔️latest
️✔️3.12
️✔️3.14

Summary

Ports the NAT Gateway V2 GA surface to core az aks, now that the 2026-06-01 API SDK (azure-mgmt-containerservice 41.6.0) is vendored (#34011). Mirrors the aks-preview extension PR Azure/azure-cli-extensions#10264 and follows the AKS NAT Gateway V2 GA API proposal.

What

az aks create / az aks update:

  • --outbound-type-sku {Standard,StandardV2} — select the managed NAT gateway SKU with --outbound-type managedNATGateway (the GA shape of NAT Gateway V2).
  • --nat-gateway-managed-outbound-ipv6-count — dual-stack IPv6 outbound IPs (StandardV2 only).
  • --nat-gateway-outbound-ips / --nat-gateway-outbound-ip-prefixes — bring-your-own public IPs / prefixes (StandardV2 only).

Validation: create requires an explicit --outbound-type managedNATGateway; update verifies the cluster's existing outbound type before applying the SKU / V2 params.

Testing

  • Unit tests (builder, validators, decorator) pass; new cases added to test_natgateway.py and test_validators.py.
  • azdev style acs: pylint + flake8 pass.
  • End-to-end validator behavior verified against a local build with SDK 41.6.0.
  • Recorded scenario test test_aks_create_and_update_with_managed_nat_gateway_v2 is scaffolded but not yet recorded — needs an azdev test ... --live run against a StandardV2-capable region. This is why the PR is a draft.

History Notes

Added an entry under AKS in src/azure-cli/HISTORY.rst.

Ports the aks-preview NAT Gateway V2 GA surface (extension PR Azure#10264) into core az aks now that the 2026-06-01 SDK (azure-mgmt-containerservice 41.6.0) is vendored.

az aks create / az aks update: add --outbound-type-sku (Standard|StandardV2) to select the managed NAT gateway SKU with --outbound-type managedNATGateway (the GA shape of NAT Gateway V2), plus the StandardV2-only --nat-gateway-managed-outbound-ipv6-count, --nat-gateway-outbound-ips and --nat-gateway-outbound-ip-prefixes. Create requires an explicit --outbound-type managedNATGateway; update verifies the cluster's existing outbound type before applying. Adds builder + validator unit tests.
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@microsoft-github-policy-service microsoft-github-policy-service Bot added the customer-reported Issues that are reported by GitHub users external to the Azure organization. label Sep 2, 2026
@microsoft-github-policy-service

Copy link
Copy Markdown
Contributor

Thank you for your contribution Christine DOSSA (@christine33-creator)! We will review the pull request and get back to you soon.

@a0x1ab

Copy link
Copy Markdown
Member

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

act-observability-squad AKS az aks/acs/openshift Auto-Assign Auto assign by bot customer-reported Issues that are reported by GitHub users external to the Azure organization.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants