diff --git a/azurerm/data_source_azuread_application_test.go b/azurerm/data_source_azuread_application_test.go index 4b28ab07d65e..641e98093738 100644 --- a/azurerm/data_source_azuread_application_test.go +++ b/azurerm/data_source_azuread_application_test.go @@ -18,6 +18,9 @@ func TestAccDataSourceAzureRMAzureADApplication_byObjectId(t *testing.T) { Providers: testAccProviders, CheckDestroy: testCheckAzureRMActiveDirectoryApplicationDestroy, Steps: []resource.TestStep{ + { + Config: testAccAzureRMActiveDirectoryApplication_basic(id), + }, { Config: config, Check: resource.ComposeTestCheckFunc( @@ -44,6 +47,9 @@ func TestAccDataSourceAzureRMAzureADApplication_byObjectIdComplete(t *testing.T) Providers: testAccProviders, CheckDestroy: testCheckAzureRMActiveDirectoryApplicationDestroy, Steps: []resource.TestStep{ + { + Config: testAccAzureRMActiveDirectoryApplication_basic(id), + }, { Config: config, Check: resource.ComposeTestCheckFunc( diff --git a/azurerm/data_source_azuread_service_principal.go b/azurerm/data_source_azuread_service_principal.go new file mode 100644 index 000000000000..eb9d12b1ac64 --- /dev/null +++ b/azurerm/data_source_azuread_service_principal.go @@ -0,0 +1,112 @@ +package azurerm + +import ( + "fmt" + + "github.com/Azure/azure-sdk-for-go/services/graphrbac/1.6/graphrbac" + "github.com/hashicorp/terraform/helper/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func dataSourceArmActiveDirectoryServicePrincipal() *schema.Resource { + return &schema.Resource{ + Read: dataSourceArmActiveDirectoryServicePrincipalRead, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + // TODO: customiseDiff to ensure either `object_id` or `display_name` or `application_id` is set + + Schema: map[string]*schema.Schema{ + "object_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ConflictsWith: []string{"display_name", "application_id"}, + }, + + "display_name": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ConflictsWith: []string{"object_id", "application_id"}, + }, + + "application_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ConflictsWith: []string{"object_id", "display_name"}, + }, + }, + } +} + +func dataSourceArmActiveDirectoryServicePrincipalRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).servicePrincipalsClient + ctx := meta.(*ArmClient).StopContext + + var servicePrincipal *graphrbac.ServicePrincipal + + if v, ok := d.GetOk("object_id"); ok { + objectId := v.(string) + app, err := client.Get(ctx, objectId) + if err != nil { + if utils.ResponseWasNotFound(app.Response) { + return fmt.Errorf("Service Principal with Object ID %q was not found!", objectId) + } + + return fmt.Errorf("Error retrieving Service Principal ID %q: %+v", objectId, err) + } + + servicePrincipal = &app + } else { + apps, err := client.ListComplete(ctx, "") + if err != nil { + return fmt.Errorf("Error listing Service Principals: %+v", err) + } + + if v, ok := d.GetOk("display_name"); ok { + displayName := v.(string) + + for _, app := range *apps.Response().Value { + if app.DisplayName == nil { + continue + } + + if *app.DisplayName == displayName { + servicePrincipal = &app + break + } + } + + if servicePrincipal == nil { + return fmt.Errorf("A Service Principal with the Display Name %q was not found", displayName) + } + } else { + applicationId := d.Get("application_id").(string) + + for _, app := range *apps.Response().Value { + if app.AppID == nil { + continue + } + + if *app.AppID == applicationId { + servicePrincipal = &app + break + } + } + + if servicePrincipal == nil { + return fmt.Errorf("A Service Principal for Application ID %q was not found", applicationId) + } + } + } + + d.SetId(*servicePrincipal.ObjectID) + + d.Set("application_id", servicePrincipal.AppID) + d.Set("display_name", servicePrincipal.DisplayName) + d.Set("object_id", servicePrincipal.ObjectID) + + return nil +} diff --git a/azurerm/data_source_azuread_service_principal_test.go b/azurerm/data_source_azuread_service_principal_test.go new file mode 100644 index 000000000000..a1ef2b857b98 --- /dev/null +++ b/azurerm/data_source_azuread_service_principal_test.go @@ -0,0 +1,111 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/google/uuid" + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccDataSourceAzureRMAzureADServicePrincipal_byApplicationId(t *testing.T) { + dataSourceName := "data.azurerm_azuread_service_principal.test" + id := uuid.New().String() + config := testAccDataSourceAzureRMAzureADServicePrincipal_byApplicationId(id) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMActiveDirectoryServicePrincipalDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMActiveDirectoryServicePrincipalExists(dataSourceName), + resource.TestCheckResourceAttrSet(dataSourceName, "application_id"), + resource.TestCheckResourceAttrSet(dataSourceName, "object_id"), + resource.TestCheckResourceAttrSet(dataSourceName, "display_name"), + ), + }, + }, + }) +} + +func TestAccDataSourceAzureRMAzureADServicePrincipal_byDisplayName(t *testing.T) { + dataSourceName := "data.azurerm_azuread_service_principal.test" + id := uuid.New().String() + config := testAccDataSourceAzureRMAzureADServicePrincipal_byDisplayName(id) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMActiveDirectoryServicePrincipalDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMActiveDirectoryServicePrincipalExists(dataSourceName), + resource.TestCheckResourceAttrSet(dataSourceName, "application_id"), + resource.TestCheckResourceAttrSet(dataSourceName, "object_id"), + resource.TestCheckResourceAttrSet(dataSourceName, "display_name"), + ), + }, + }, + }) +} + +func TestAccDataSourceAzureRMAzureADServicePrincipal_byObjectId(t *testing.T) { + dataSourceName := "data.azurerm_azuread_service_principal.test" + id := uuid.New().String() + config := testAccDataSourceAzureRMAzureADServicePrincipal_byObjectId(id) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMActiveDirectoryServicePrincipalDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMActiveDirectoryServicePrincipalExists(dataSourceName), + resource.TestCheckResourceAttrSet(dataSourceName, "application_id"), + resource.TestCheckResourceAttrSet(dataSourceName, "object_id"), + resource.TestCheckResourceAttrSet(dataSourceName, "display_name"), + ), + }, + }, + }) +} + +func testAccDataSourceAzureRMAzureADServicePrincipal_byApplicationId(id string) string { + template := testAccAzureRMActiveDirectoryServicePrincipal_basic(id) + return fmt.Sprintf(` +%s + +data "azurerm_azuread_service_principal" "test" { + application_id = "${azurerm_azuread_service_principal.test.application_id}" +} +`, template) +} + +func testAccDataSourceAzureRMAzureADServicePrincipal_byDisplayName(id string) string { + template := testAccAzureRMActiveDirectoryServicePrincipal_basic(id) + return fmt.Sprintf(` +%s + +data "azurerm_azuread_service_principal" "test" { + display_name = "${azurerm_azuread_service_principal.test.display_name}" +} +`, template) +} + +func testAccDataSourceAzureRMAzureADServicePrincipal_byObjectId(id string) string { + template := testAccAzureRMActiveDirectoryServicePrincipal_basic(id) + return fmt.Sprintf(` +%s + +data "azurerm_azuread_service_principal" "test" { + object_id = "${azurerm_azuread_service_principal.test.id}" +} +`, template) +} diff --git a/azurerm/provider.go b/azurerm/provider.go index 3d5177993be9..8e7eee3ea80b 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -79,6 +79,7 @@ func Provider() terraform.ResourceProvider { DataSourcesMap: map[string]*schema.Resource{ "azurerm_azuread_application": dataSourceArmAzureADApplication(), + "azurerm_azuread_service_principal": dataSourceArmActiveDirectoryServicePrincipal(), "azurerm_application_security_group": dataSourceArmApplicationSecurityGroup(), "azurerm_app_service": dataSourceArmAppService(), "azurerm_app_service_plan": dataSourceAppServicePlan(), diff --git a/website/azurerm.erb b/website/azurerm.erb index 58dff0531c9d..b57ee6f658d8 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -27,10 +27,6 @@