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

#9775 aperta il 2 giu 2026

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

Metriche repository

Star
 (4859 star)
Metriche merge PR
 (Merge medio 2g 23h) (146 PR mergiate in 30 g)

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