Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Resource: azurerm_data_factory_linked_service_synapse #9928

Merged
38 changes: 38 additions & 0 deletions azurerm/internal/services/datafactory/data_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,41 @@ func serializeDataFactoryPipelineActivities(activities *[]datafactory.BasicActiv
func suppressJsonOrderingDifference(_, old, new string, _ *schema.ResourceData) bool {
return utils.NormalizeJson(old) == utils.NormalizeJson(new)
}

func expandAzureKeyVaultPasswordReference(input []interface{}) *datafactory.AzureKeyVaultSecretReference {
if len(input) == 0 || input[0] == nil {
return nil
}

config := input[0].(map[string]interface{})

keyVaultLinkedServiceName := config["linked_service_name"].(string)
keyVaultPasswordSecretName := config["password_secret_name"].(string)
linkedServiceType := "LinkedServiceReference"

return &datafactory.AzureKeyVaultSecretReference{
SecretName: keyVaultPasswordSecretName,
Store: &datafactory.LinkedServiceReference{
Type: &linkedServiceType,
ReferenceName: &keyVaultLinkedServiceName,
},
}
}

func flattenAzureKeyVaultPasswordReference(secretReference *datafactory.AzureKeyVaultSecretReference) []interface{} {
if secretReference == nil {
return nil
}

parameters := make(map[string]interface{})

if store := secretReference.Store; store != nil {
if store.ReferenceName != nil {
parameters["linked_service_name"] = *store.ReferenceName
}
}

parameters["password_secret_name"] = secretReference.SecretName

return []interface{}{parameters}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,289 @@
package datafactory

import (
"fmt"
"log"
"time"

"github.com/Azure/azure-sdk-for-go/services/datafactory/mgmt/2018-06-01/datafactory"
"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/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceArmDataFactoryLinkedServiceSynapse() *schema.Resource {
return &schema.Resource{
Create: resourceArmDataFactoryLinkedServiceSynapseCreateUpdate,
Read: resourceArmDataFactoryLinkedServiceSynapseRead,
Update: resourceArmDataFactoryLinkedServiceSynapseCreateUpdate,
Delete: resourceArmDataFactoryLinkedServiceSynapseDelete,

Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(30 * time.Minute),
Read: schema.DefaultTimeout(5 * time.Minute),
Update: schema.DefaultTimeout(30 * time.Minute),
Delete: schema.DefaultTimeout(30 * time.Minute),
},

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateAzureRMDataFactoryLinkedServiceDatasetName,
},

"data_factory_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.DataFactoryName(),
},

// There's a bug in the Azure API where this is returned in lower-case
// BUG: https://github.com/Azure/azure-rest-api-specs/issues/5788
"resource_group_name": azure.SchemaResourceGroupNameDiffSuppress(),

"connection_string": {
Type: schema.TypeString,
Required: true,
DiffSuppressFunc: azureRmDataFactoryLinkedServiceConnectionStringDiff,
ValidateFunc: validation.StringIsNotEmpty,
},

"key_vault_password_reference": {
allantargino marked this conversation as resolved.
Show resolved Hide resolved
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"linked_service_name": {
allantargino marked this conversation as resolved.
Show resolved Hide resolved
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringIsNotEmpty,
},

"password_secret_name": {
allantargino marked this conversation as resolved.
Show resolved Hide resolved
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringIsNotEmpty,
},
},
},
},

"description": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringIsNotEmpty,
},

"integration_runtime_name": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringIsNotEmpty,
},

"parameters": {
Type: schema.TypeMap,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
allantargino marked this conversation as resolved.
Show resolved Hide resolved
},

"annotations": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
allantargino marked this conversation as resolved.
Show resolved Hide resolved
},

"additional_properties": {
Type: schema.TypeMap,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
allantargino marked this conversation as resolved.
Show resolved Hide resolved
},
},
}
}

func resourceArmDataFactoryLinkedServiceSynapseCreateUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).DataFactory.LinkedServiceClient
ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()

name := d.Get("name").(string)
dataFactoryName := d.Get("data_factory_name").(string)
resourceGroup := d.Get("resource_group_name").(string)

if d.IsNewResource() {
existing, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "")
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("Error checking for presence of existing Data Factory Linked Service Synapse%q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err)
}
}

if existing.ID != nil && *existing.ID != "" {
return tf.ImportAsExistsError("azurerm_data_factory_linked_service_synapse", *existing.ID)
}
}

passwordReference := d.Get("key_vault_password_reference").([]interface{})

sqlDWProperties := &datafactory.AzureSQLDWLinkedServiceTypeProperties{
ConnectionString: d.Get("connection_string").(string),
Password: expandAzureKeyVaultPasswordReference(passwordReference),
}

description := d.Get("description").(string)

sqlDWLinkedService := &datafactory.AzureSQLDWLinkedService{
Description: &description,
AzureSQLDWLinkedServiceTypeProperties: sqlDWProperties,
Type: datafactory.TypeAzureSQLDW,
}
allantargino marked this conversation as resolved.
Show resolved Hide resolved

if v, ok := d.GetOk("parameters"); ok {
sqlDWLinkedService.Parameters = expandDataFactoryParameters(v.(map[string]interface{}))
}

if v, ok := d.GetOk("integration_runtime_name"); ok {
sqlDWLinkedService.ConnectVia = expandDataFactoryLinkedServiceIntegrationRuntime(v.(string))
}

if v, ok := d.GetOk("additional_properties"); ok {
sqlDWLinkedService.AdditionalProperties = v.(map[string]interface{})
}

if v, ok := d.GetOk("annotations"); ok {
annotations := v.([]interface{})
sqlDWLinkedService.Annotations = &annotations
}

linkedService := datafactory.LinkedServiceResource{
Properties: sqlDWLinkedService,
}

if _, err := client.CreateOrUpdate(ctx, resourceGroup, dataFactoryName, name, linkedService, ""); err != nil {
return fmt.Errorf("Error creating/updating Data Factory Linked Service Synapse %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err)
}

resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "")
if err != nil {
return fmt.Errorf("Error retrieving Data Factory Linked Service Synapse %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err)
}

if resp.ID == nil {
return fmt.Errorf("Cannot read Data Factory Linked Service Synapse %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err)
}

d.SetId(*resp.ID)

return resourceArmDataFactoryLinkedServiceSynapseRead(d, meta)
}

func resourceArmDataFactoryLinkedServiceSynapseRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).DataFactory.LinkedServiceClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := azure.ParseAzureResourceID(d.Id())
if err != nil {
return err
}
resourceGroup := id.ResourceGroup
dataFactoryName := id.Path["factories"]
name := id.Path["linkedservices"]
allantargino marked this conversation as resolved.
Show resolved Hide resolved

resp, err := client.Get(ctx, resourceGroup, dataFactoryName, name, "")
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
d.SetId("")
return nil
}

return fmt.Errorf("Error retrieving Data Factory Linked Service Synapse %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err)
}

d.Set("name", resp.Name)
d.Set("resource_group_name", resourceGroup)
d.Set("data_factory_name", dataFactoryName)

sqlDW, ok := resp.Properties.AsAzureSQLDWLinkedService()
if !ok {
return fmt.Errorf("Error classifiying Data Factory Linked Service Synapse %q (Data Factory %q / Resource Group %q): Expected: %q Received: %q", name, dataFactoryName, resourceGroup, datafactory.TypeAzureSQLDW, *resp.Type)
}

d.Set("additional_properties", sqlDW.AdditionalProperties)
d.Set("description", sqlDW.Description)

annotations := flattenDataFactoryAnnotations(sqlDW.Annotations)
if err := d.Set("annotations", annotations); err != nil {
return fmt.Errorf("Error setting `annotations`: %+v", err)
}

parameters := flattenDataFactoryParameters(sqlDW.Parameters)
if err := d.Set("parameters", parameters); err != nil {
return fmt.Errorf("Error setting `parameters`: %+v", err)
}

if connectVia := sqlDW.ConnectVia; connectVia != nil {
if connectVia.ReferenceName != nil {
d.Set("integration_runtime_name", connectVia.ReferenceName)
}
}

if properties := sqlDW.AzureSQLDWLinkedServiceTypeProperties; properties != nil {
if properties.ConnectionString != nil {
if val, ok := properties.ConnectionString.(string); ok {
d.Set("connection_string", val)
} else {
d.Set("connection_string", "")
log.Printf("[DEBUG] Skipping connection string %q since it's not a string", val)
}
}

if err := d.Set("key_vault_password_reference", flattenAzureKeyVaultPasswordReference(properties.Password)); err != nil {
return fmt.Errorf("setting `key_vault_password_reference`: %+v", err)
}
}

return nil
}

func resourceArmDataFactoryLinkedServiceSynapseDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).DataFactory.LinkedServiceClient
ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := azure.ParseAzureResourceID(d.Id())
if err != nil {
return err
}
resourceGroup := id.ResourceGroup
dataFactoryName := id.Path["factories"]
name := id.Path["linkedservices"]
allantargino marked this conversation as resolved.
Show resolved Hide resolved

response, err := client.Delete(ctx, resourceGroup, dataFactoryName, name)
if err != nil {
if !utils.ResponseWasNotFound(response) {
return fmt.Errorf("Error deleting Data Factory Linked Service Synapse %q (Data Factory %q / Resource Group %q): %+v", name, dataFactoryName, resourceGroup, err)
}
}

return nil
}
Loading