Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions internal/services/cognitive/ai_services_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,15 @@ import (
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

var _ sdk.ResourceWithUpdate = AIServices{}
func (r AIServices) DeprecatedInFavourOfResource() string {
return "azurerm_cognitive_account"
}

var _ sdk.ResourceWithCustomImporter = AIServices{}
var (
_ sdk.ResourceWithUpdate = AIServices{}
_ sdk.ResourceWithCustomImporter = AIServices{}
_ sdk.ResourceWithDeprecationReplacedBy = AIServices{}
)

type AIServices struct{}

Expand Down
25 changes: 25 additions & 0 deletions internal/services/cognitive/ai_services_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,16 @@ import (
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance"
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/features"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
)

type AIServices struct{}

func TestAccCognitiveAIServices_basic(t *testing.T) {
if features.FivePointOh() {
t.Skipf("Skipping since `azurerm_ai_services` is deprecated and will be removed in 5.0")
}
data := acceptance.BuildTestData(t, "azurerm_ai_services", "test")
r := AIServices{}

Expand All @@ -38,6 +42,9 @@ func TestAccCognitiveAIServices_basic(t *testing.T) {
}

func TestAccCognitiveAIServices_requiresImport(t *testing.T) {
if features.FivePointOh() {
t.Skipf("Skipping since `azurerm_ai_services` is deprecated and will be removed in 5.0")
}
data := acceptance.BuildTestData(t, "azurerm_ai_services", "test")
r := AIServices{}

Expand All @@ -53,6 +60,9 @@ func TestAccCognitiveAIServices_requiresImport(t *testing.T) {
}

func TestAccCognitiveAIServices_complete(t *testing.T) {
if features.FivePointOh() {
t.Skipf("Skipping since `azurerm_ai_services` is deprecated and will be removed in 5.0")
}
data := acceptance.BuildTestData(t, "azurerm_ai_services", "test")
r := AIServices{}

Expand All @@ -70,6 +80,9 @@ func TestAccCognitiveAIServices_complete(t *testing.T) {
}

func TestAccCognitiveAIServices_update(t *testing.T) {
if features.FivePointOh() {
t.Skipf("Skipping since `azurerm_ai_services` is deprecated and will be removed in 5.0")
}
data := acceptance.BuildTestData(t, "azurerm_ai_services", "test")
r := AIServices{}

Expand All @@ -90,6 +103,9 @@ func TestAccCognitiveAIServices_update(t *testing.T) {
}

func TestAccCognitiveAIServices_networkACLs(t *testing.T) {
if features.FivePointOh() {
t.Skipf("Skipping since `azurerm_ai_services` is deprecated and will be removed in 5.0")
}
data := acceptance.BuildTestData(t, "azurerm_ai_services", "test")
r := AIServices{}

Expand Down Expand Up @@ -119,6 +135,9 @@ func TestAccCognitiveAIServices_networkACLs(t *testing.T) {
}

func TestAccCognitiveAIServices_identity(t *testing.T) {
if features.FivePointOh() {
t.Skipf("Skipping since `azurerm_ai_services` is deprecated and will be removed in 5.0")
}
data := acceptance.BuildTestData(t, "azurerm_ai_services", "test")
r := AIServices{}

Expand Down Expand Up @@ -159,6 +178,9 @@ func TestAccCognitiveAIServices_identity(t *testing.T) {
}

func TestAccCognitiveAIServices_customerManagedKey_update(t *testing.T) {
if features.FivePointOh() {
t.Skipf("Skipping since `azurerm_ai_services` is deprecated and will be removed in 5.0")
}
data := acceptance.BuildTestData(t, "azurerm_ai_services", "test")
r := AIServices{}

Expand Down Expand Up @@ -192,6 +214,9 @@ func TestAccCognitiveAIServices_customerManagedKey_update(t *testing.T) {
}

func TestAccCognitiveAIServices_KVHsmManagedKey(t *testing.T) {
if features.FivePointOh() {
t.Skipf("Skipping since `azurerm_ai_services` is deprecated and will be removed in 5.0")
}
if os.Getenv("ARM_TEST_HSM_KEY") == "" {
t.Skip("Skipping as ARM_TEST_HSM_KEY is not specified")
return
Expand Down
10 changes: 8 additions & 2 deletions internal/services/cognitive/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package cognitive
import (
"github.com/hashicorp/terraform-plugin-framework/action"
"github.com/hashicorp/terraform-plugin-framework/ephemeral"
"github.com/hashicorp/terraform-provider-azurerm/internal/features"
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
)
Expand Down Expand Up @@ -58,13 +59,18 @@ func (r Registration) DataSources() []sdk.DataSource {

// Resources returns a list of Resources supported by this Service
func (r Registration) Resources() []sdk.Resource {
return []sdk.Resource{
AIServices{},
resources := []sdk.Resource{
CognitiveAccountProjectResource{},
CognitiveAccountRaiPolicyResource{},
CognitiveDeploymentResource{},
CognitiveRaiBlocklistResource{},
}

if !features.FivePointOh() {
resources = append(resources, AIServices{})
}

return resources
}

func (r Registration) Actions() []func() action.Action {
Expand Down
16 changes: 5 additions & 11 deletions internal/services/machinelearning/ai_foundry_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ provider "azurerm" {

resource "azurerm_ai_foundry" "test" {
name = "acctestaihub-%[2]d"
location = azurerm_ai_services.test.location
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
storage_account_id = azurerm_storage_account.test.id
key_vault_id = azurerm_key_vault.test.id
Expand Down Expand Up @@ -195,7 +195,7 @@ resource "azurerm_user_assigned_identity" "test" {

resource "azurerm_ai_foundry" "test" {
name = "acctestaihub-%[2]d"
location = azurerm_ai_services.test.location
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
storage_account_id = azurerm_storage_account.test.id
key_vault_id = azurerm_key_vault.test.id
Expand Down Expand Up @@ -270,7 +270,7 @@ resource "azurerm_user_assigned_identity" "test2" {

resource "azurerm_ai_foundry" "test" {
name = "acctestaihub-%[2]d"
location = azurerm_ai_services.test.location
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
storage_account_id = azurerm_storage_account.test.id
key_vault_id = azurerm_key_vault.test.id
Expand Down Expand Up @@ -358,7 +358,7 @@ resource "azurerm_role_assignment" "test_kv" {

resource "azurerm_ai_foundry" "test" {
name = "acctestaihub-%[2]d"
location = azurerm_ai_services.test.location
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
storage_account_id = azurerm_storage_account.test.id
key_vault_id = azurerm_key_vault.test.id
Expand Down Expand Up @@ -417,7 +417,7 @@ resource "azurerm_key_vault_key" "test" {

resource "azurerm_ai_foundry" "test" {
name = "acctestaihub-%[2]d"
location = azurerm_ai_services.test.location
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
storage_account_id = azurerm_storage_account.test.id
key_vault_id = azurerm_key_vault.test.id
Expand Down Expand Up @@ -496,11 +496,5 @@ resource "azurerm_storage_account" "test" {
account_replication_type = "LRS"
}

resource "azurerm_ai_services" "test" {
Comment thread
magodo marked this conversation as resolved.
name = "acctestaiservices-%[1]d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
sku_name = "S0"
}
`, data.RandomInteger, data.Locations.Primary, data.RandomString)
}
20 changes: 19 additions & 1 deletion website/docs/5.0-upgrade-guide.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ More information on [how to pin the version of a Terraform Provider being used c
## What's changed in Version 5.0 of the Azure Provider?

* [Resource Provider Registration Changes](#resource-provider-registration-changes)
* [Migration Guide for `azurerm_ai_services`](#migration-guide-for-removed-azurerm_ai_services-resource)
* [Removed Resources](#removed-resources)
* [Removed Data Sources](#removed-data-sources)
* [Breaking Changes in Resources](#breaking-changes-in-resources)
Expand Down Expand Up @@ -111,6 +112,20 @@ This change was made because:

The legacy `ARM_PROVIDER_ENHANCED_VALIDATION` environment variable, which previously controlled both location and resource provider validation, has been removed in version 5.0. Please migrate to either the `enhanced_validation` provider block or the specific environment variables: `ARM_PROVIDER_ENHANCED_VALIDATION_LOCATIONS` and `ARM_PROVIDER_ENHANCED_VALIDATION_RESOURCE_PROVIDERS`.

## Migration guide for removed `azurerm_ai_services` resource

The `azurerm_ai_services` resource has been removed and replaced by `azurerm_cognitive_account`. The table below lists the attributes that have changed; all other attributes are carried over unchanged.

| `azurerm_ai_services` | `azurerm_cognitive_account` | Notes |
|-----------------------|-----------------------------|-------|
| (not present) | `kind` | **Required**. Set to `"AIServices"` to match the behaviour of `azurerm_ai_services`. |
| `local_authentication_enabled` | `local_auth_enabled` | **Renamed**. Both default to `true`. |
| `public_network_access` | `public_network_access_enabled` | **Changed type**. String (`"Enabled"` / `"Disabled"`) → Boolean (`true` / `false`). Defaults to `true`. |
| (not present) | `project_management_enabled` |**Required**. Set to `true` to match the behaviour of `azurerm_ai_services`. |
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

project_management_enabled is not a required field in cognitive_account. Also in ai_services we never set any value. Are you saying the API default when it's nil is equal to true?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not a "REQUIRED" field but it's required to be set to true during migration, otherwise it will force a new resource to be created based on this instruction.

I may change the wording to Mandatory to make it less confusing with the "Required" field terminology?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To add some more context, project_management_enabled flag is optional and false by default as it's not applicable to other kinds. Users should be setting the project_management_enabled to true when kind is set to AIServices. Without it, users can't create projects within the account which defeats the purpose.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah got it thanks!

Also noted we already got a CustomizeDiff check for this in cognitive_account:

internal/services/cognitive/cognitive_account_resource.go

			if d.Get("project_management_enabled").(bool) {
				if kind != "AIServices" {
					return errors.New("`project_management_enabled` can only be set to `true` when `kind` is set to `AIServices`")
				}

| `customer_managed_key.managed_hsm_key_id` | (not present) | Use `customer_managed_key.key_vault_key_id` property, it can accept both regular and HSM key id. |

~> **Note:** If your configuration included a `storage` block under `azurerm_ai_services`, `terraform plan` may show changes after migration even though the Azure resource itself has not changed. This occurs because `azurerm_ai_services` silently ignored the `storage` block and never sent those values to the API, so the imported state does not reflect them. Running `terraform apply` will reconcile the state by applying the storage configuration for the first time.

## Removed Resources

Please follow the format in the example below for adding removed resources:
Expand All @@ -121,6 +136,10 @@ Please follow the format in the example below for adding removed resources:
This deprecated resource has been superseded/retired and has been removed from the Azure Provider.
```

### `azurerm_ai_services`

* This deprecated resource has been superseded by `azurerm_cognitive_account` and has been removed from the Azure Provider.

### `azurerm_automation_software_update_configuration`

* This deprecated resource has been retired and has been removed from the Azure Provider.
Expand Down Expand Up @@ -221,7 +240,6 @@ This deprecated resource has been superseded/retired and has been removed from t

* This deprecated resource has been retired and has been removed from the Azure Provider.


## Removed Data Sources

Please follow the format in the example below for adding removed data sources:
Expand Down
9 changes: 1 addition & 8 deletions website/docs/r/ai_foundry.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,9 @@ resource "azurerm_storage_account" "example" {
account_replication_type = "LRS"
}

resource "azurerm_ai_services" "example" {
name = "exampleaiservices"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
sku_name = "S0"
}

resource "azurerm_ai_foundry" "example" {
name = "exampleaihub"
location = azurerm_ai_services.example.location
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
storage_account_id = azurerm_storage_account.example.id
key_vault_id = azurerm_key_vault.example.id
Expand Down
9 changes: 1 addition & 8 deletions website/docs/r/ai_foundry_project.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,9 @@ resource "azurerm_storage_account" "example" {
account_replication_type = "LRS"
}

resource "azurerm_ai_services" "example" {
name = "exampleaiservices"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
sku_name = "S0"
}

resource "azurerm_ai_foundry" "example" {
name = "exampleaihub"
location = azurerm_ai_services.example.location
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
storage_account_id = azurerm_storage_account.example.id
key_vault_id = azurerm_key_vault.example.id
Expand Down
3 changes: 3 additions & 0 deletions website/docs/r/ai_services.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ description: |-

Manages an AI Services Account.

~> **Note:** The `azurerm_ai_services` resource has been deprecated and will be removed in v5.0 of the AzureRM Provider. Please use [`azurerm_cognitive_account`](cognitive_account.html.markdown) resource instead.


## Example Usage

```hcl
Expand Down