skypilot-org/skypilot

[Azure] _create_storage_account passes a raw dict instead of a typed model, breaking on azure-mgmt-storage 25.0.0

Open

Aperta il 2 giu 2026

Vedi su GitHub
 (0 commenti) (0 reazioni) (0 assegnatari)Python (4859 star) (311 fork)batch import
good first issue

Descrizione

Background

PR #9774 pins azure-mgmt-storage<25.0.0 to unblock CI/usage, but only mitigates the symptom. This issue tracks the proper fix.

Problem

sky/data/storage.py:_create_storage_account passes a hand-built dict with a top-level encryption key to storage_accounts.begin_create:

self.storage_client.storage_accounts.begin_create(
    resource_group_name, storage_account_name, {
        'sku': {'name': 'Standard_GRS'},
        'kind': 'StorageV2',
        'location': self.region,
        'encryption': {                       # <-- top-level
            'services': {'blob': {'key_type': 'Account', 'enabled': True}},
            'key_source': 'Microsoft.Storage'
        },
    }).result()

On the wire, encryption belongs under properties (properties.encryption). Whether the malformed top-level key is corrected depends on the SDK version:

  • azure-mgmt-storage <= 24.x (msrest): the serializer remaps the dict via _attribute_map (encryptionproperties.encryption), so the body is correct and the call succeeds.

  • azure-mgmt-storage 25.0.0 (TypeSpec / _model_base): _create_initial does json.dumps(parameters, cls=SdkJSONEncoder) — a dict is serialized verbatim, with no key remapping. The body keeps encryption at the top level, and ARM rejects it:

    (InvalidRequestContent) The request content was invalid and could not be deserialized:
    'Could not find member 'encryption' on object of type 'ResourceDefinition'.
    Path 'encryption', line 1, position 84.'
    

Relying on the SDK to silently fix a malformed dict is fragile; the dict shape is not portable across SDK serializers.

Proposed fix

Pass a typed StorageAccountCreateParameters model object (with Sku, Encryption, EncryptionServices, EncryptionService) instead of a raw dict. The model serializes to the correct properties.encryption body under both msrest (<=24.x) and the TypeSpec encoder (25.x), which also lets us drop the <25.0.0 pin afterward.

While here, audit other raw-dict begin_create / begin_create_or_update calls for the same latent issue, e.g.:

  • sky/data/storage.py (storage account create; blob container create)
  • sky/adaptors/azure.py
  • sky/provision/azure/ ARM deployment / resource-group bodies

Repro (offline, no Azure account)

Serialize SkyPilot's exact dict through each SDK version:

  • 24.0.0{..., "properties": {"encryption": {...}}} (correct)
  • 25.0.0{..., "encryption": {...}} (top-level; matches the ARM error)

Guida contributor