|
| 1 | +--- |
| 2 | +layout: collection-browser-doc |
| 3 | +title: Azure modules |
| 4 | +category: migrating-to-v1 |
| 5 | +excerpt: >- |
| 6 | + Migrate Azure tests from Terratest pre-v1 to v1.0.0. |
| 7 | +tags: ["azure", "migration", "v1"] |
| 8 | +order: 300 |
| 9 | +nav_title: Documentation |
| 10 | +nav_title_link: /docs/ |
| 11 | +--- |
| 12 | + |
| 13 | +The `modules/azure` package received the largest set of breaking changes in |
| 14 | +the v1.0.0 release. This guide walks through what changed and how to update |
| 15 | +your tests. |
| 16 | + |
| 17 | +## Why we migrated |
| 18 | + |
| 19 | +The previous version of `modules/azure` was built on |
| 20 | +`github.com/Azure/azure-sdk-for-go/services/...`, the legacy "track 1" Azure |
| 21 | +SDK. Microsoft has archived that SDK; it no longer receives feature updates, |
| 22 | +bug fixes, or security patches. |
| 23 | + |
| 24 | +v1.0.0 moves the entire package to |
| 25 | +`github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/...`, the modular, |
| 26 | +actively maintained "track 2" SDK. The new SDK has a different shape: typed |
| 27 | +resource clients are produced by a `ClientFactory`, response payloads put |
| 28 | +most fields on a nested `Properties` struct, and pagination uses pagers |
| 29 | +instead of iterators. We took the opportunity to land a few small API |
| 30 | +cleanups at the same time so v1.0.0 ships a coherent, stable surface. |
| 31 | + |
| 32 | +## What changed at a glance |
| 33 | + |
| 34 | +- All Azure service code now imports `sdk/resourcemanager/<service>/arm<service>` packages instead of `services/<service>/mgmt/<api-version>/<service>`. |
| 35 | +- Resource fields moved under `.Properties` (e.g. `vm.StorageProfile` is now `vm.Properties.StorageProfile`). |
| 36 | +- Iterator-based list calls (`NextWithContext`) are replaced with pagers (`NewListPager` / `More` / `NextPage`). |
| 37 | +- 8 deprecated `Get*ClientE` client-getter functions were removed; the `Create*ClientE` replacements have been around for a while. |
| 38 | +- 4 `CreateNew*ClientContextE` factories were renamed to `Create*ClientContextE`. The old names remain as deprecated aliases. |
| 39 | +- `NsgRuleSummary.SourceAdresssPrefixes` (triple-s typo) was renamed to `SourceAddressPrefixes`. |
| 40 | +- A new `*WithClient` family of functions was added so tests can inject a fake or pre-built SDK client (useful with the Azure SDK's `azfake` package). |
| 41 | +- `GetVirtualMachineImage` / `GetVirtualMachineImageE` now return `*VMImage` instead of `VMImage`. |
| 42 | + |
| 43 | +## Updating SDK imports |
| 44 | + |
| 45 | +Most Terratest users do not import the underlying Azure SDK directly, |
| 46 | +because Terratest wraps it. If you only call `terratest/modules/azure` |
| 47 | +helpers, you can usually skip this section. If your tests do import the SDK |
| 48 | +(for example to construct request objects or assert on returned types), |
| 49 | +update imports as follows: |
| 50 | + |
| 51 | +| Old (`services/...`) | New (`sdk/resourcemanager/...`) | |
| 52 | +| --- | --- | |
| 53 | +| `github.com/Azure/azure-sdk-for-go/services/compute/mgmt/.../compute` | `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6` | |
| 54 | +| `github.com/Azure/azure-sdk-for-go/services/network/mgmt/.../network` | `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v6` | |
| 55 | +| `github.com/Azure/azure-sdk-for-go/services/storage/mgmt/.../storage` | `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage` | |
| 56 | +| `github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/.../documentdb` | `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/cosmos/armcosmos/v3` | |
| 57 | +| `github.com/Azure/azure-sdk-for-go/services/servicebus/mgmt/.../servicebus` | `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/servicebus/armservicebus/v2` | |
| 58 | +| `github.com/Azure/azure-sdk-for-go/services/preview/containerservice/.../containerservice` | `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v6` | |
| 59 | +| `github.com/Azure/azure-sdk-for-go/services/containerregistry/mgmt/.../containerregistry` | `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerregistry/armcontainerregistry` | |
| 60 | +| `github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/.../containerinstance` | `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerinstance/armcontainerinstance/v2` | |
| 61 | +| `github.com/Azure/azure-sdk-for-go/services/preview/operationalinsights/.../operationalinsights` | `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/operationalinsights/armoperationalinsights/v2` | |
| 62 | +| `github.com/Azure/azure-sdk-for-go/services/resources/mgmt/.../subscriptions` | `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions` | |
| 63 | +| `github.com/Azure/azure-sdk-for-go/services/resources/mgmt/.../resources` | `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources` | |
| 64 | +| `github.com/Azure/azure-sdk-for-go/services/privatedns/mgmt/.../privatedns` | `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns` | |
| 65 | +| `github.com/Azure/azure-sdk-for-go/profiles/latest/frontdoor/mgmt/frontdoor` | `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/frontdoor/armfrontdoor` | |
| 66 | +| `github.com/Azure/azure-sdk-for-go/profiles/preview/preview/monitor/mgmt/insights` | `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/monitor/armmonitor` | |
| 67 | +| `github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/.../recoveryservices` | `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/recoveryservices/armrecoveryservices` | |
| 68 | +| `github.com/Azure/azure-sdk-for-go/services/recoveryservices/mgmt/.../backup` | `github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/recoveryservices/armrecoveryservicesbackup/v4` | |
| 69 | + |
| 70 | +Once imports are updated, expect three follow-on edits per file: |
| 71 | + |
| 72 | +1. **Type names** lose their old prefix and gain `arm`. For example |
| 73 | + `compute.VirtualMachine` becomes `armcompute.VirtualMachine`, |
| 74 | + `network.SecurityGroup` becomes `armnetwork.SecurityGroup`, and |
| 75 | + `storage.Account` becomes `armstorage.Account`. |
| 76 | +2. **Field access** moves under `.Properties`. For example |
| 77 | + `vm.StorageProfile` becomes `vm.Properties.StorageProfile`, and |
| 78 | + `registry.LoginServer` becomes `registry.Properties.LoginServer`. |
| 79 | +3. **List iteration** moves to the pager pattern: replace |
| 80 | + `iterator.NextWithContext(ctx)` loops with |
| 81 | + `for pager.More() { page, err := pager.NextPage(ctx); ... }`. |
| 82 | + |
| 83 | +## Renamed factory functions |
| 84 | + |
| 85 | +Four client factories were renamed to drop the redundant `New` (a |
| 86 | +`Create*New*Client` reads as redundant). The old names remain as deprecated |
| 87 | +aliases for one minor release; please update at your convenience. |
| 88 | + |
| 89 | +| Old name | New name | |
| 90 | +| --- | --- | |
| 91 | +| `CreateNewNetworkInterfacesClientE` | `CreateNetworkInterfacesClientE` | |
| 92 | +| `CreateNewNetworkInterfacesClientContextE` | `CreateNetworkInterfacesClientContextE` | |
| 93 | +| `CreateNewNetworkInterfaceIPConfigurationClientE` | `CreateNetworkInterfaceIPConfigurationClientE` | |
| 94 | +| `CreateNewNetworkInterfaceIPConfigurationClientContextE` | `CreateNetworkInterfaceIPConfigurationClientContextE` | |
| 95 | +| `CreateNewSubnetClientE` | `CreateSubnetClientE` | |
| 96 | +| `CreateNewSubnetClientContextE` | `CreateSubnetClientContextE` | |
| 97 | +| `CreateNewVirtualNetworkClientE` | `CreateVirtualNetworkClientE` | |
| 98 | +| `CreateNewVirtualNetworkClientContextE` | `CreateVirtualNetworkClientContextE` | |
| 99 | + |
| 100 | +## Removed deprecated functions |
| 101 | + |
| 102 | +The previous release marked eight client-getter functions for removal |
| 103 | +("`TODO: remove in next version`"). v1.0.0 is that version. Each removed |
| 104 | +function has a long-standing `Create*ClientE` replacement. |
| 105 | + |
| 106 | +| Removed | Replacement | |
| 107 | +| --- | --- | |
| 108 | +| `GetAvailabilitySetClientE` | `CreateAvailabilitySetClientE` | |
| 109 | +| `GetDiskClientE` | `CreateDisksClientE` | |
| 110 | +| `GetDiagnosticsSettingsClientE` | `CreateDiagnosticsSettingsClientE` | |
| 111 | +| `GetVMInsightsClientE` | `CreateVMInsightsClientE` | |
| 112 | +| `GetActivityLogAlertsClientE` | `CreateActivityLogAlertsClientE` | |
| 113 | +| `GetResourceGroupClientE` | `CreateResourceGroupClientE` | |
| 114 | +| `GetStorageAccountClientE` | `CreateStorageAccountClientE` | |
| 115 | +| `GetStorageBlobContainerClientE` | `CreateStorageBlobContainerClientE` | |
| 116 | + |
| 117 | +The replacements take the same arguments and return the same client type |
| 118 | +(now from the new SDK). The rename is mechanical: `Get` → `Create`. Note |
| 119 | +that `GetDiskClientE` becomes `CreateDisksClientE` (plural) to match the |
| 120 | +underlying SDK's `DisksClient` type. |
| 121 | + |
| 122 | +## Typo fix on `NsgRuleSummary` |
| 123 | + |
| 124 | +`NsgRuleSummary.SourceAdresssPrefixes` (note the three s's) was renamed to |
| 125 | +the correctly-spelled `SourceAddressPrefixes`. The field type |
| 126 | +(`[]string`) is unchanged. Update any code that read or set this field: |
| 127 | + |
| 128 | +```go |
| 129 | +// Before |
| 130 | +for _, prefix := range rule.SourceAdresssPrefixes { |
| 131 | + // ... |
| 132 | +} |
| 133 | + |
| 134 | +// After |
| 135 | +for _, prefix := range rule.SourceAddressPrefixes { |
| 136 | + // ... |
| 137 | +} |
| 138 | +``` |
| 139 | + |
| 140 | +The paired `DestinationAddressPrefixes` field was already spelled |
| 141 | +correctly and is unchanged. |
| 142 | + |
| 143 | +## `VMImage` is now a pointer |
| 144 | + |
| 145 | +`GetVirtualMachineImage` and `GetVirtualMachineImageE` now return |
| 146 | +`*VMImage` instead of `VMImage`, matching every other resource getter in |
| 147 | +the package. |
| 148 | + |
| 149 | +```go |
| 150 | +// Before |
| 151 | +img := azure.GetVirtualMachineImage(t, vmName, rg, sub) |
| 152 | +fmt.Println(img.Publisher) |
| 153 | + |
| 154 | +// After |
| 155 | +img := azure.GetVirtualMachineImage(t, vmName, rg, sub) |
| 156 | +if img != nil { |
| 157 | + fmt.Println(img.Publisher) |
| 158 | +} |
| 159 | +``` |
| 160 | + |
| 161 | +If the resource cannot be loaded the function still fails the test, so |
| 162 | +the `nil` guard is precautionary. |
| 163 | + |
| 164 | +## New `WithClient` variants for testability |
| 165 | + |
| 166 | +v1.0.0 adds a parallel family of `*WithClient` functions across all Azure |
| 167 | +modules. Each one accepts a pre-built SDK client and a |
| 168 | +`context.Context`, so you can drive Terratest helpers against the Azure |
| 169 | +SDK's `azfake` fake-server framework in unit tests: |
| 170 | + |
| 171 | +```go |
| 172 | +import ( |
| 173 | + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6" |
| 174 | + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6/fake" |
| 175 | +) |
| 176 | + |
| 177 | +// Build a fake client that returns a canned response. |
| 178 | +fakeServer := fake.DisksServer{ /* ... */ } |
| 179 | +client, _ := armcompute.NewDisksClient("sub-id", nil, &arm.ClientOptions{ |
| 180 | + ClientOptions: azcore.ClientOptions{ |
| 181 | + Transport: fake.NewDisksServerTransport(&fakeServer), |
| 182 | + }, |
| 183 | +}) |
| 184 | + |
| 185 | +disk, err := azure.GetDiskWithClient(ctx, client, resourceGroup, diskName) |
| 186 | +``` |
| 187 | + |
| 188 | +This is purely additive: the existing `*ContextE` functions still work and |
| 189 | +build their own clients from ambient credentials. Use `WithClient` |
| 190 | +variants only if you need test injection. |
| 191 | + |
| 192 | +## Search-and-replace cheatsheet |
| 193 | + |
| 194 | +Most projects can do the bulk of the migration with a few find/replace |
| 195 | +passes. The snippets below cover the most common edits: |
| 196 | + |
| 197 | +```bash |
| 198 | +# Removed Get*ClientE functions -> Create*ClientE |
| 199 | +sd 'GetAvailabilitySetClientE\b' 'CreateAvailabilitySetClientE' $(rg -l 'GetAvailabilitySetClientE') |
| 200 | +sd 'GetDiskClientE\b' 'CreateDisksClientE' $(rg -l 'GetDiskClientE') |
| 201 | +sd 'GetDiagnosticsSettingsClientE\b' 'CreateDiagnosticsSettingsClientE' $(rg -l 'GetDiagnosticsSettingsClientE') |
| 202 | +sd 'GetVMInsightsClientE\b' 'CreateVMInsightsClientE' $(rg -l 'GetVMInsightsClientE') |
| 203 | +sd 'GetActivityLogAlertsClientE\b' 'CreateActivityLogAlertsClientE' $(rg -l 'GetActivityLogAlertsClientE') |
| 204 | +sd 'GetResourceGroupClientE\b' 'CreateResourceGroupClientE' $(rg -l 'GetResourceGroupClientE') |
| 205 | +sd 'GetStorageAccountClientE\b' 'CreateStorageAccountClientE' $(rg -l 'GetStorageAccountClientE') |
| 206 | +sd 'GetStorageBlobContainerClientE\b' 'CreateStorageBlobContainerClientE' $(rg -l 'GetStorageBlobContainerClientE') |
| 207 | + |
| 208 | +# CreateNew*Client renames |
| 209 | +sd 'CreateNewNetworkInterfacesClient' 'CreateNetworkInterfacesClient' $(rg -l 'CreateNewNetworkInterfacesClient') |
| 210 | +sd 'CreateNewNetworkInterfaceIPConfigurationClient' 'CreateNetworkInterfaceIPConfigurationClient' $(rg -l 'CreateNewNetworkInterfaceIPConfigurationClient') |
| 211 | +sd 'CreateNewSubnetClient' 'CreateSubnetClient' $(rg -l 'CreateNewSubnetClient') |
| 212 | +sd 'CreateNewVirtualNetworkClient' 'CreateVirtualNetworkClient' $(rg -l 'CreateNewVirtualNetworkClient') |
| 213 | + |
| 214 | +# NsgRuleSummary typo |
| 215 | +sd 'SourceAdresssPrefixes' 'SourceAddressPrefixes' $(rg -l 'SourceAdresssPrefixes') |
| 216 | +``` |
| 217 | + |
| 218 | +For the SDK migration itself we recommend doing one Azure service at a |
| 219 | +time, starting with the import path, then fixing the resulting compile |
| 220 | +errors (type names, `.Properties` access, pager loops). The Go compiler |
| 221 | +is the most reliable migration tool here. |
| 222 | + |
| 223 | +## Need help |
| 224 | + |
| 225 | +Open an issue on the Terratest repo with the `azure` label and a snippet |
| 226 | +of the failing code. If you spot a gap in this guide, please send a PR |
| 227 | +against `docs/_docs/03_migrating-to-v1/azure.md`. |
0 commit comments