When specifying the sku for postgres and redis (and probably some other resources) you need to repeat yourself when specifying SKUs, example:
resource "azurerm_postgresql_server" "test" {
  name                = "postgresql-server-1"
  sku {
    name = "B_Gen4_2"
    capacity = 2
    tier = "Basic"
    family = "Gen4"
  }
β¦
}
resource "azurerm_redis_cache" "test" {
  name                = "tf-redis-basic"
  family              = "C"
  sku_name            = "Basic"
β¦
}
resource "azurerm_application_gateway" "network" {
  name                = "my-application-gateway-12345"
  sku {
    name           = "Standard_Small"
    tier           = "Standard"
    capacity       = 2
  }
β¦
}
There is unnecessary repetition here - e.g. we can eliminate name from the pg resource and family from redis since they can be 100% inferred from the other values
resource "azurerm_postgresql_server" "test" {
  name                = "postgresql-server-1"
  sku {
    capacity = 2
    tier = "Basic"
    family = "Gen4"
  }
β¦
}
resource "azurerm_postgresql_server" "test" {
  name                = "postgresql-server-1"
  sku {
    name = "B_Gen4_2"
  }
β¦
}
resource "azurerm_redis_cache" "test" {
  name                = "tf-redis-basic"
  sku_name            = "Basic"
β¦
}
resource "azurerm_application_gateway" "network" {
  name                = "my-application-gateway-12345"
  sku {
    name           = "Standard_Small"
    capacity       = 2
  }
β¦
}
ΓΈ
Regarding the choice of:
  sku {
    capacity = 2
    tier = "Basic"
    family = "Gen4"
  }
vs.
  sku {
    name = "B_Gen4_2"
  }
It would of course be more flexible to allow both forms, but if I were to choose one I would prefer the first as it lets logic decisions be easily made on each component.
The resources essentially wrap the Azure/azure-rest-api-specs repo. I don't know if deviating from the swagger specs is the best idea. Defaults might be a happy medium here, but not ideal.
@lfshr we deviate from the Go SDK repository where it makes sense to provide a better UX - I'd agree this'd be a good example of where we should deviate. Thinking about this, I think the best path here would be to make the name field optional and compute it from the other fields for the following reasons:
capacity:  3 => 2B (the first character of the name field in the example above) will mean Basic (for example, in the past Basic has been renamed Classic, and ManagedBasic was introduced to certain resources); whereas the inverse is true.This means we should be able to make this block:
 sku {
  capacity = 2
  tier = "Basic"
  family = "Gen4"
}
I can't give a timeframe for getting to this at the moment, but this is something I think we should do π
I am proposing to flatten the below 17 resources:
The SKU attributes in all of these resources would no longer be defined in block groups but rather as a single attribute, for example:
resource "azurerm_postgresql_server" "test" {
  name      = "postgresql-server-1"
  sku_name  = "B_Gen4_2"
}
resource "resource_arm_express_route_circuit" "test" {
  name      = "express-route-circuit-1"
  sku_name  = "Standard_Metered"
}
resource "resource_arm_cognitive_account" "test" {
  name      = "cognitive-account-1"
  sku_name  = "P2_Premium"
}
resource "azurerm_app_service_plan" "test" {
  name      = "app-service-plan-1"
  sku_name  = "Dynamic_Y1"
}
NOTE: For backwards compatibility I will leave the existing sku structure as is and mark it as deprecated. The existing sku attribute will be removed in the 2.0 timeframe.
@WodansSon,
I have opened some more PRs to address the outstanding resources. of the remaining ones i think azurerm_application_gateway, azurerm_express_route_circuit, azurerm_signalr_service are fine as is. 
I'm going to close this as only app service and mssql elastic pool remain and they are a bit more complicated and require more thought.
This has been released in version 2.0.0 of the provider. Please see the Terraform documentation on provider versioning or reach out if you need any assistance upgrading. As an example:
provider "azurerm" {
    version = "~> 2.0.0"
}
# ... other configuration ...
I'm going to lock this issue because it has been closed for _30 days_ β³. This helps our maintainers find and focus on the active issues.
If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error π€ π , please reach out to my human friends π [email protected]. Thanks!
Most helpful comment
@lfshr we deviate from the Go SDK repository where it makes sense to provide a better UX - I'd agree this'd be a good example of where we should deviate. Thinking about this, I think the best path here would be to make the
namefield optional and compute it from the other fields for the following reasons:capacity: 3 => 2B(the first character of thenamefield in the example above) will meanBasic(for example, in the past Basic has been renamed Classic, and ManagedBasic was introduced to certain resources); whereas the inverse is true.This means we should be able to make this block:
I can't give a timeframe for getting to this at the moment, but this is something I think we should do π