diff --git a/internal/services/datafactory/data_factory_integration_runtime_azure_ssis_resource.go b/internal/services/datafactory/data_factory_integration_runtime_azure_ssis_resource.go index c056414efb29..ab59b864181f 100644 --- a/internal/services/datafactory/data_factory_integration_runtime_azure_ssis_resource.go +++ b/internal/services/datafactory/data_factory_integration_runtime_azure_ssis_resource.go @@ -107,6 +107,12 @@ func resourceDataFactoryIntegrationRuntimeAzureSsis() *pluginsdk.Resource { ValidateFunc: validation.IntBetween(1, 16), }, + "credential_name": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + "edition": { Type: pluginsdk.TypeString, Optional: true, @@ -564,6 +570,10 @@ func resourceDataFactoryIntegrationRuntimeAzureSsisRead(d *pluginsdk.ResourceDat return fmt.Errorf("setting `catalog_info`: %+v", err) } + if err := d.Set("credential_name", flattenDataFactoryIntegrationRuntimeUserAssignedCredential(ssisProps.Credential)); err != nil { + return fmt.Errorf("setting `credential_name`: %+v", err) + } + if err := d.Set("custom_setup_script", flattenDataFactoryIntegrationRuntimeAzureSsisCustomSetupScript(ssisProps.CustomSetupScriptProperties, d)); err != nil { return fmt.Errorf("setting `custom_setup_script`: %+v", err) } @@ -648,6 +658,13 @@ func expandDataFactoryIntegrationRuntimeAzureSsisProperties(d *pluginsdk.Resourc PackageStores: expandDataFactoryIntegrationRuntimeAzureSsisPackageStore(d.Get("package_store").([]interface{})), } + if credentialName := d.Get("credential_name"); credentialName.(string) != "" { + ssisProperties.Credential = &datafactory.CredentialReference{ + ReferenceName: utils.String(credentialName.(string)), + Type: utils.String("CredentialReference"), + } + } + if catalogInfos, ok := d.GetOk("catalog_info"); ok && len(catalogInfos.([]interface{})) > 0 { catalogInfo := catalogInfos.([]interface{})[0].(map[string]interface{}) @@ -937,6 +954,14 @@ func flattenDataFactoryIntegrationRuntimeAzureSsisProxy(input *datafactory.Integ } } +func flattenDataFactoryIntegrationRuntimeUserAssignedCredential(credentialProperties *datafactory.CredentialReference) *string { + if credentialProperties == nil { + return nil + } + + return credentialProperties.ReferenceName +} + func flattenDataFactoryIntegrationRuntimeAzureSsisCustomSetupScript(customSetupScriptProperties *datafactory.IntegrationRuntimeCustomSetupScriptProperties, d *pluginsdk.ResourceData) []interface{} { if customSetupScriptProperties == nil { return []interface{}{} diff --git a/internal/services/datafactory/data_factory_integration_runtime_azure_ssis_resource_test.go b/internal/services/datafactory/data_factory_integration_runtime_azure_ssis_resource_test.go index b651d85fd075..4a0192847678 100644 --- a/internal/services/datafactory/data_factory_integration_runtime_azure_ssis_resource_test.go +++ b/internal/services/datafactory/data_factory_integration_runtime_azure_ssis_resource_test.go @@ -150,6 +150,21 @@ func TestAccDataFactoryIntegrationRuntimeManagedSsis_aadAuth(t *testing.T) { }) } +func TestAccDataFactoryIntegrationRuntimeManagedSsis_userAssignedManagedCredentials(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_data_factory_integration_runtime_azure_ssis", "test") + r := IntegrationRuntimeManagedSsisResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.userAssignedManagedCredentials(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + func TestAccDataFactoryIntegrationRuntimeManagedSsis_expressVnetInjection(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_data_factory_integration_runtime_azure_ssis", "test") r := IntegrationRuntimeManagedSsisResource{} @@ -846,6 +861,74 @@ resource "azurerm_data_factory_integration_runtime_azure_ssis" "test" { `, data.RandomInteger, data.Locations.Primary, data.RandomString) } +func (IntegrationRuntimeManagedSsisResource) userAssignedManagedCredentials(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-df-%d" + location = "%s" +} + +resource "azurerm_user_assigned_identity" "test" { + location = azurerm_resource_group.test.location + name = "testuser%d" + resource_group_name = azurerm_resource_group.test.name +} + +resource "azurerm_data_factory" "test" { + name = "acctestdfirm%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + identity { + type = "UserAssigned" + identity_ids = [azurerm_user_assigned_identity.test.id] + } +} + +resource "azurerm_data_factory_credential_user_managed_identity" "test" { + name = "credential%d" + data_factory_id = azurerm_data_factory.test.id + identity_id = azurerm_user_assigned_identity.test.id +} + +resource "azurerm_sql_server" "test" { + name = "acctestsql%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + version = "12.0" + administrator_login = "ssis_catalog_admin" + administrator_login_password = "my-s3cret-p4ssword!" +} + +resource "azurerm_sql_active_directory_administrator" "test" { + server_name = azurerm_sql_server.test.name + resource_group_name = azurerm_resource_group.test.name + login = azurerm_data_factory.test.name + tenant_id = azurerm_user_assigned_identity.test.tenant_id + object_id = azurerm_user_assigned_identity.test.principal_id +} + +resource "azurerm_data_factory_integration_runtime_azure_ssis" "test" { + name = "managed-integration-runtime-%d" + data_factory_id = azurerm_data_factory.test.id + location = azurerm_resource_group.test.location + node_size = "Standard_D8_v3" + credential_name = azurerm_data_factory_credential_user_managed_identity.test.name + + catalog_info { + server_endpoint = azurerm_sql_server.test.fully_qualified_domain_name + pricing_tier = "Basic" + } + + depends_on = [azurerm_sql_active_directory_administrator.test] +} + `, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger) +} + func (t IntegrationRuntimeManagedSsisResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { id, err := parse.IntegrationRuntimeID(state.ID) if err != nil { diff --git a/website/docs/r/data_factory_integration_runtime_azure_ssis.html.markdown b/website/docs/r/data_factory_integration_runtime_azure_ssis.html.markdown index b9e42992a324..2ef869d732a4 100644 --- a/website/docs/r/data_factory_integration_runtime_azure_ssis.html.markdown +++ b/website/docs/r/data_factory_integration_runtime_azure_ssis.html.markdown @@ -47,6 +47,10 @@ The following arguments are supported: * `number_of_nodes` - (Optional) Number of nodes for the Azure-SSIS Integration Runtime. Max is `10`. Defaults to `1`. +* `credential_name` - (Optional) The name of a Data Factory Credential that the SSIS integration will use to access data sources. For example, [`azurerm_data_factory_credential_user_managed_identity`](data_factory_credential_user_assigned_managed_identity.html.html) + +~> **NOTE** If `credential_name` is omitted, the integration runtime will use the Data Factory assigned identity. + * `max_parallel_executions_per_node` - (Optional) Defines the maximum parallel executions per node. Defaults to `1`. Max is `1`. * `edition` - (Optional) The Azure-SSIS Integration Runtime edition. Valid values are `Standard` and `Enterprise`. Defaults to `Standard`.