Skip to content

Commit

Permalink
azurerm_kusto_cluster - Support for identity (hashicorp#7367)
Browse files Browse the repository at this point in the history
  • Loading branch information
jrauschenbusch committed Jun 29, 2020
1 parent a8fd145 commit f899b35
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 0 deletions.
91 changes: 91 additions & 0 deletions azurerm/helpers/azure/kusto.go
@@ -0,0 +1,91 @@
package azure

import (
"github.com/Azure/azure-sdk-for-go/services/kusto/mgmt/2020-02-15/kusto"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress"
)

func SchemaKustoIdentity() *schema.Schema {
return &schema.Schema{
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{
string(kusto.IdentityTypeNone),
string(kusto.IdentityTypeSystemAssigned),
}, true),
DiffSuppressFunc: suppress.CaseDifference,
},
"principal_id": {
Type: schema.TypeString,
Computed: true,
},
"tenant_id": {
Type: schema.TypeString,
Computed: true,
},
"identity_ids": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
},
}
}

func ExpandKustoIdentity(input []interface{}) *kusto.Identity {
if len(input) == 0 || input[0] == nil {
return nil
}
identity := input[0].(map[string]interface{})
identityType := kusto.IdentityType(identity["type"].(string))

kustoIdentity := kusto.Identity{
Type: identityType,
}

return &kustoIdentity
}

func FlattenKustoIdentity(input *kusto.Identity) []interface{} {
if input == nil || input.Type == kusto.IdentityTypeNone {
return []interface{}{}
}

identityIds := make([]string, 0)
if input.UserAssignedIdentities != nil {
for k := range input.UserAssignedIdentities {
identityIds = append(identityIds, k)
}
}

principalID := ""
if input.PrincipalID != nil {
principalID = *input.PrincipalID
}

tenantID := ""
if input.TenantID != nil {
tenantID = *input.TenantID
}

return []interface{}{
map[string]interface{}{
"type": string(input.Type),
"identity_ids": identityIds,
"principal_id": principalID,
"tenant_id": tenantID,
},
}
}
12 changes: 12 additions & 0 deletions azurerm/internal/services/kusto/kusto_cluster_resource.go
Expand Up @@ -50,6 +50,8 @@ func resourceArmKustoCluster() *schema.Resource {

"location": azure.SchemaLocation(),

"identity": azure.SchemaKustoIdentity(),

"sku": {
Type: schema.TypeList,
Required: true,
Expand Down Expand Up @@ -169,6 +171,12 @@ func resourceArmKustoClusterCreateUpdate(d *schema.ResourceData, meta interface{
Tags: tags.Expand(t),
}

if _, ok := d.GetOk("identity"); ok {
kustoIdentityRaw := d.Get("identity").([]interface{})
kustoIdentity := azure.ExpandKustoIdentity(kustoIdentityRaw)
kustoCluster.Identity = kustoIdentity
}

future, err := client.CreateOrUpdate(ctx, resourceGroup, name, kustoCluster)
if err != nil {
return fmt.Errorf("Error creating or updating Kusto Cluster %q (Resource Group %q): %+v", name, resourceGroup, err)
Expand Down Expand Up @@ -219,6 +227,10 @@ func resourceArmKustoClusterRead(d *schema.ResourceData, meta interface{}) error
d.Set("location", azure.NormalizeLocation(*location))
}

if err := d.Set("identity", azure.FlattenKustoIdentity(clusterResponse.Identity)); err != nil {
return fmt.Errorf("Error setting `identity`: %s", err)
}

if err := d.Set("sku", flattenKustoClusterSku(clusterResponse.Sku)); err != nil {
return fmt.Errorf("Error setting `sku`: %+v", err)
}
Expand Down
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
Expand Down Expand Up @@ -129,6 +130,28 @@ func TestAccAzureRMKustoCluster_sku(t *testing.T) {
})
}

func TestAccAzureRMKustoCluster_identitySystemAssigned(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_kusto_cluster", "test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: testCheckAzureRMKustoClusterDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMKustoCluster_identitySystemAssigned(data),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMKustoClusterExists(data.ResourceName),
resource.TestCheckResourceAttr(data.ResourceName, "identity.0.type", "SystemAssigned"),
resource.TestCheckResourceAttr(data.ResourceName, "identity.0.identity_ids.#", "0"),
resource.TestMatchResourceAttr(data.ResourceName, "identity.0.principal_id", validate.UUIDRegExp),
),
},
data.ImportStep(),
},
})
}

func testAccAzureRMKustoCluster_basic(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
Expand Down Expand Up @@ -261,6 +284,34 @@ resource "azurerm_kusto_cluster" "test" {
`, data.RandomInteger, data.Locations.Primary, data.RandomString)
}

func testAccAzureRMKustoCluster_identitySystemAssigned(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}
resource "azurerm_kusto_cluster" "test" {
name = "acctestkc%s"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
sku {
name = "Dev(No SLA)_Standard_D11_v2"
capacity = 1
}
identity {
type = "SystemAssigned"
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomString)
}

func testCheckAzureRMKustoClusterDestroy(s *terraform.State) error {
client := acceptance.AzureProvider.Meta().(*clients.Client).Kusto.ClustersClient
ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext
Expand Down
15 changes: 15 additions & 0 deletions website/docs/r/kusto_cluster.html.markdown
Expand Up @@ -46,6 +46,8 @@ The following arguments are supported:

* `sku` - (Required) A `sku` block as defined below.

* `identity` - (Optional) A identity block.

* `enable_disk_encryption` - (Optional) Specifies if the cluster's disks are encrypted.

* `enable_streaming_ingest` - (Optional) Specifies if the streaming ingest is enabled.
Expand All @@ -62,6 +64,19 @@ A `sku` block supports the following:

* `capacity` - (Required) Specifies the node count for the cluster. Boundaries depend on the sku name.

---

An `identity` block supports the following:

* `type` - (Required) Specifies the type of Managed Service Identity that is configured on this Kusto Cluster. Possible values are: `SystemAssigned` (where Azure will generate a Service Principal for you).

* `principal_id` - (Computed) Specifies the Principal ID of the System Assigned Managed Service Identity that is configured on this Kusto Cluster.

* `tenant_id` - (Computed) Specifies the Tenant ID of the System Assigned Managed Service Identity that is configured on this Kusto Cluster.

* `identity_ids` - (Computed) The list of user identities associated with the Kusto cluster.

~> **NOTE:** When `type` is set to `SystemAssigned`, the Principal ID can be retrieved after the cluster has been created. More details are available below. See [documentation](https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/overview) for additional information.

## Attributes Reference

Expand Down

0 comments on commit f899b35

Please sign in to comment.