diff --git a/azurerm/data_source_user_assigned_identity.go b/azurerm/data_source_user_assigned_identity.go new file mode 100644 index 000000000000..ec3c4c88b35d --- /dev/null +++ b/azurerm/data_source_user_assigned_identity.go @@ -0,0 +1,77 @@ +package azurerm + +import ( + "fmt" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func dataSourceArmUserAssignedIdentity() *schema.Resource { + return &schema.Resource{ + Read: dataSourceArmUserAssignedIdentityRead, + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(1, 24), + }, + + "resource_group_name": resourceGroupNameForDataSourceSchema(), + + "location": locationForDataSourceSchema(), + + "principal_id": { + Type: schema.TypeString, + Computed: true, + }, + + "client_id": { + Type: schema.TypeString, + Computed: true, + }, + + "tags": tagsForDataSourceSchema(), + }, + } +} + +func dataSourceArmUserAssignedIdentityRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).userAssignedIdentitiesClient + ctx := meta.(*ArmClient).StopContext + + name := d.Get("name").(string) + resourceGroup := d.Get("resource_group_name").(string) + + resp, err := client.Get(ctx, resourceGroup, name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error making Read request on User Assigned Identity %q (Resource Group %q): %+v", name, resourceGroup, err) + } + + d.SetId(*resp.ID) + + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + if props := resp.IdentityProperties; props != nil { + if principalId := props.PrincipalID; principalId != nil { + d.Set("principal_id", principalId.String()) + } + + if clientId := props.ClientID; clientId != nil { + d.Set("client_id", clientId.String()) + } + } + + flattenAndSetTags(d, resp.Tags) + + return nil +} diff --git a/azurerm/data_source_user_assigned_identity_test.go b/azurerm/data_source_user_assigned_identity_test.go new file mode 100644 index 000000000000..899375a0c280 --- /dev/null +++ b/azurerm/data_source_user_assigned_identity_test.go @@ -0,0 +1,90 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" +) + +func TestAccDataSourceAzureRMUserAssignedIdentity_basic(t *testing.T) { + dataSourceName := "data.azurerm_user_assigned_identity.test" + resourceName := "azurerm_user_assigned_identity.test" + ri := tf.AccRandTimeInt() + rs := acctest.RandString(4) + + location := testLocation() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceAzureRMUserAssignedIdentity_basic(ri, testLocation(), rs), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "name", fmt.Sprintf("acctest%s-uai", rs)), + resource.TestCheckResourceAttr(dataSourceName, "resource_group_name", fmt.Sprintf("acctest%d-rg", ri)), + resource.TestCheckResourceAttr(dataSourceName, "location", azureRMNormalizeLocation(location)), + resource.TestMatchResourceAttr(dataSourceName, "principal_id", validate.UUIDRegExp), + resource.TestMatchResourceAttr(dataSourceName, "client_id", validate.UUIDRegExp), + resource.TestCheckResourceAttr(dataSourceName, "tags.%", "1"), + testEqualResourceAttr(dataSourceName, resourceName, "principal_id"), + testEqualResourceAttr(dataSourceName, resourceName, "client_id"), + ), + }, + }, + }) +} + +func testEqualResourceAttr(dataSourceName string, resourceName string, attrName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + ds, ok := s.RootModule().Resources[dataSourceName] + if !ok { + return fmt.Errorf("Not found: %s", dataSourceName) + } + + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + dsAttr := ds.Primary.Attributes[attrName] + rsAttr := rs.Primary.Attributes[attrName] + + if dsAttr != rsAttr { + return fmt.Errorf("Attributes not equal: %s, %s", dsAttr, rsAttr) + } + + return nil + } +} + +func testAccDataSourceAzureRMUserAssignedIdentity_basic(rInt int, location string, rString string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctest%d-rg" + location = "%s" +} + +resource "azurerm_user_assigned_identity" "test" { + name = "acctest%s-uai" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "${azurerm_resource_group.test.location}" + + tags = { + "foo" = "bar" + } +} + +data "azurerm_user_assigned_identity" "test" { + name = "${azurerm_user_assigned_identity.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" +} +`, rInt, location, rString) +} diff --git a/azurerm/provider.go b/azurerm/provider.go index 60eeed2e8886..0e0ac889663b 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -167,6 +167,7 @@ func Provider() terraform.ResourceProvider { "azurerm_subscription": dataSourceArmSubscription(), "azurerm_subscriptions": dataSourceArmSubscriptions(), "azurerm_traffic_manager_geographical_location": dataSourceArmTrafficManagerGeographicalLocation(), + "azurerm_user_assigned_identity": dataSourceArmUserAssignedIdentity(), "azurerm_virtual_machine": dataSourceArmVirtualMachine(), "azurerm_virtual_network_gateway": dataSourceArmVirtualNetworkGateway(), "azurerm_virtual_network": dataSourceArmVirtualNetwork(), diff --git a/azurerm/resource_arm_user_assigned_identity_test.go b/azurerm/resource_arm_user_assigned_identity_test.go index bc553d1d7a27..424fcee51ff6 100644 --- a/azurerm/resource_arm_user_assigned_identity_test.go +++ b/azurerm/resource_arm_user_assigned_identity_test.go @@ -2,11 +2,12 @@ package azurerm import ( "fmt" - "regexp" "testing" "net/http" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/hashicorp/terraform/helper/acctest" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/terraform" @@ -14,7 +15,6 @@ import ( ) func TestAccAzureRMUserAssignedIdentity_basic(t *testing.T) { - generatedUuidRegex := "^[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}$" resourceName := "azurerm_user_assigned_identity.test" ri := tf.AccRandTimeInt() rs := acctest.RandString(14) @@ -28,8 +28,8 @@ func TestAccAzureRMUserAssignedIdentity_basic(t *testing.T) { Config: testAccAzureRMUserAssignedIdentity_basic(ri, testLocation(), rs), Check: resource.ComposeTestCheckFunc( testCheckAzureRMUserAssignedIdentityExists(resourceName), - resource.TestMatchResourceAttr(resourceName, "principal_id", regexp.MustCompile(generatedUuidRegex)), - resource.TestMatchResourceAttr(resourceName, "client_id", regexp.MustCompile(generatedUuidRegex)), + resource.TestMatchResourceAttr(resourceName, "principal_id", validate.UUIDRegExp), + resource.TestMatchResourceAttr(resourceName, "client_id", validate.UUIDRegExp), ), }, { @@ -46,7 +46,6 @@ func TestAccAzureRMUserAssignedIdentity_requiresImport(t *testing.T) { return } - generatedUuidRegex := "^[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}$" resourceName := "azurerm_user_assigned_identity.test" ri := tf.AccRandTimeInt() rs := acctest.RandString(14) @@ -60,8 +59,8 @@ func TestAccAzureRMUserAssignedIdentity_requiresImport(t *testing.T) { Config: testAccAzureRMUserAssignedIdentity_basic(ri, testLocation(), rs), Check: resource.ComposeTestCheckFunc( testCheckAzureRMUserAssignedIdentityExists(resourceName), - resource.TestMatchResourceAttr(resourceName, "principal_id", regexp.MustCompile(generatedUuidRegex)), - resource.TestMatchResourceAttr(resourceName, "client_id", regexp.MustCompile(generatedUuidRegex)), + resource.TestMatchResourceAttr(resourceName, "principal_id", validate.UUIDRegExp), + resource.TestMatchResourceAttr(resourceName, "client_id", validate.UUIDRegExp), ), }, { diff --git a/website/azurerm.erb b/website/azurerm.erb index d1f74c33bfc8..659819b0e60c 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -327,6 +327,10 @@ azurerm_traffic_manager_geographical_location + > + azurerm_user_assigned_identity + + > azurerm_virtual_machine diff --git a/website/docs/d/user_assigned_identity.html.markdown b/website/docs/d/user_assigned_identity.html.markdown new file mode 100644 index 000000000000..ddd6da471315 --- /dev/null +++ b/website/docs/d/user_assigned_identity.html.markdown @@ -0,0 +1,44 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azure_user_assigned_identity" +sidebar_current: "docs-azurerm-datasource-user-assigned-identity" +description: |- + Gets information about an existing User Assigned Identity. + +--- + +# Data Source: azurerm_user_assigned_identity + +Use this data source to access information about an existing User Assigned Identity. + +## Example Usage (reference an existing) + +```hcl +data "azurerm_user_assigned_identity" "example" { + name = "name_of_user_assigned_identity" + resource_group_name = "name_of_resource_group" +} + +output "uai_client_id" { + value = "${data.azurerm_user_assigned_identity.example.client_id}" +} + +output "uai_principal_id" { + value = "${data.azurerm_user_assigned_identity.example.principal_id}" +} +``` + +## Argument Reference + +* `name` - (Required) The name of the User Assigned Identity. +* `resource_group_name` - (Required) The name of the Resource Group in which the User Assigned Identity exists. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Resource ID of the User Assigned Identity. +* `location` - The Azure location where the User Assigned Identity exists. +* `principal_id` - The Service Principal ID of the User Assigned Identity. +* `client_id` - The Client ID of the User Assigned Identity. +* `tags` - A mapping of tags assigned to the User Assigned Identity. \ No newline at end of file